表格(表头放置组件)

表格(表头放置组件)

本来今天想写JTable的单元格合并的,但是突然想到明天早上要赶飞机去参加大学同学的婚礼,可能时间会不够,所以写JTableHeader了,还简单点.

前面已经把JTable的单元格的操作已经讲的差不多了,现在说一下JTableHeader,其实JTableHeaderJTable的单元格很类似,也可以实现RendererEditor.但是JTableHeaderUI还是比较复杂的,设置也和JTable的单元格是不一样的,所以很多特殊效果是实现不了的,比如鼠标的进入和离开的渲染(有知道的可以教教我,这个效果我实验了好久,都不好用.),当然很多时候对于JTableHeader来说,根本不需要实现复杂的效果,这里我们只介绍简单的效果.

首先是JTableHeader的鼠标事件,然后是JTableHeader上面放置Java的组件,然后是JTableHeader的合并和拆分例子.当然对于JTableHeader来说还有tooltip提示以及排序过滤等,这些就不夹杂在这里讲了,单独开个专题:

先看最普通的JTableHeader的鼠标事件,如图:

实现很简单,增加JTableHeader的鼠标监听就可以了:

       //add jtable header listener

       table.getTableHeader().addMouseListener(new MouseListener() {

然后判断监听里触发事件的是不是JTableHeader

       @Override

           publicvoid mouseClicked(MouseEvent e) {

              if (e.getSource() instanceof JTableHeader) {

                  if (SwingUtilities.isRightMouseButton(e)

然后在下面写JTableHeader上的鼠标右键事件就可以了,还有就是一些基本属性,比如背景色、前景色、字体、宽度等,直接使用table.getTableHeader().setXXX就可以了.

接下里和JTable的单元格很类似,也是RendererEditor,就不全说了,参考JTable的单元格的例子就可以了,这儿先讲个最简单的Renderer

实现效果如题,JTableHeader换为JButton效果:

只需要实现TableCellRenderer接口就可以了:

publicclass MyHeaderButtonRenderer extends JButton implements

        TableCellRenderer

然后实现接口的方法:

    @Override

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

设置JButton的属性:

    Color fgColor = null;

    Color bgColor = null;

    if (hasFocus) {

          fgColor = UIManager.getColor("TableHeader.focusCellForeground");

          bgColor = UIManager.getColor("TableHeader.focusCellBackground");

     }

     if (fgColor == null) {

          fgColor = header.getForeground();

     }

     if (bgColor == null) {

           bgColor = header.getBackground();

     }

     setForeground(fgColor);

     setBackground(bgColor);     

    button.setText((value == null) ? "" : value.toString());

然后比较重要的是设置JTableHeader高度的:

     // set height.

        if (headerHeight != 0) {

            setPreferredSize(new Dimension(getWidth(), headerHeight));

        } else {

            setPreferredSize(new Dimension(getWidth(), getHeight()));

        }

然后我们需要提供一个方法给外部来设置高度:

    /**

     *settableheaderheight.

     */

    publicvoid setHeight(int headerheight) {

        headerHeight = headerheight;

    }

只需要注意这一点,但我们直接使用Java提供的JTableHeadersetSize来设置的时候,表面是没有问题的,但是当我们拖动ScrollBar的时候可能出现绘制重叠的问题,这就是因为我们设置的ViewUI不同步造成的,我们需要在Rnederer里设置,它是最后加载和渲染的,就不会出现绘制重叠的问题了.

还有一个例子,JTableHeader的列字数太多时,需要分行显示,在晚上见有人使用JtextArea来实现,这样既可以自动换行,但是存在一个简单问题就是编辑效果不好处理,这里我用另外一种方法实现,使用Jlist,可以实现多行了,当然由此也可以实现自定义的组件,比如一个JPanel,在它上面可以放置其它组件的集合.

先看看效果:

这个和JButton是一样的,继承JList实现TableCellRenderer就可以了,设置一些Jlist的属性:

publicclass MyHeaderListRenderer extends JList implements TableCellRenderer {

设置属性:

       setForeground(UIManager.getColor("TableHeader.foreground"));

       setBackground(UIManager.getColor("TableHeader.background"));

       setBorder(UIManager.getBorder("TableHeader.cellBorder"));

       ListCellRenderer renderer = getCellRenderer();

       ((JLabel) renderer).setHorizontalAlignment(JLabel.CENTER);

       setCellRenderer(renderer);

然后实现TableCellRenderer的方法:

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

在里面设置

    setListData(vector);

就完成了,使用和前面一样:

    TableCellRenderer renderer = new MyHeaderListRenderer();

    Enumeration<?> enumTemp = table.getColumnModel().getColumns();

    while (enumTemp.hasMoreElements()) {

((TableColumn) enumTemp.nextElement()).setHeaderRenderer(renderer);

    }

本来不想写这个例子的,但是为了放置某些看到人以为JTableHeader只能反正单个的类似JbuttonJLabel这样的组件,所以做了个JList上去,从简单到复杂甚至你放个JTable上去也可以的,当然要看你的需要了.

至于Editor的例子,Rnederer的例子很相似,实现TableCellEditor接口,然后设置JTableHeadersetHeaderEditor就可以了,就不再写了,参考JTable的单元格的Editor就可以.

最后再写给RendererEditor混合的例子,和前面讲的JTable的单元格一样,也存在事件的问题和显示的问题,如果不但需要显示,还需要编辑的呈现,必须同时设置RendererEditor.

先看效果:




它实现简单的效果很简单,只需要实现JCombobox类型的RendererEditor.就可以了:

先看Renderer:

publicclass MyHeaderComboxRenderer extends JComboBox implements

       TableCellRenderer, MouseListener {

需要继承JComboBox,实现TableCellRenderer接口,另外实现MouseListener接口的目的是我们鼠标点击时希望触发的是JComboboxPopUp事件,而不是JTableHeader的编辑事件.

构造函数里我们添加JComboboxItem

    public MyHeaderComboxRenderer(String[] items) {

       for (int i = 0; i < items.length; i++) {

           addItem(items[i]);

       }

    }

然后是实现TableCellRenderer的方法,设置属性,和前面JButton基本一致:

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

setBorder(border);

       combox.setSelectedItem((value == null) ? "" : value.toString());

其它的设置背景色和字体、高度的参考JButton那个Renderer就可以了.

最后是处理鼠标事件,如果不处理的话可能有这种情况出现,没有弹出JCombobox而进入了单元格的编辑状态:

这当然不是我们愿意见到的,所以自己处理一下鼠标点击:

    /**

     *Invokedwhenamousebuttonhasbeenpressedonacomponent.

     */

    publicvoid mouseClicked(MouseEvent e) {

       this.firePopupMenuWillBecomeVisible();

    }

至于Editor我们使用Sun提供给我们的就可以了,

new DefaultCellEditor(combox)

最后就是使用了,

String[] items = { "首选项", "次选项", "末选项" };

TableCellRenderer renderer = new MyHeaderComboxRenderer(items);

table.getColumnModel().getColumn(1).setHeaderValue(combo.getItemAt(0));

table.getColumnModel().getColumn(1).setHeaderRenderer(renderer);

table.getColumnModel().getColumn(1).setHeaderEditor(new DefaultCellEditor(combo));

到这里,基本的JTableHeader就算完成了,当然实际应用中如果你只是这么简单的设置的话可

能会有绘制和刷新的问题,尤其是JTable频繁更新的时候,这时候你需要重写JTableHeader

UIJTableHeader,如下所示:

publicclass MyGroupTableHeaderUI extends BasicTableHeaderUI {

publicclass MyTableHeader extends JTableHeader implements CellEditorListener

甚至需要的时候TableColumn也要重写:

publicclass MyTableColumn extends TableColumn {

这里就不详细介绍这个了,一是一般用不到,而是下个专题介绍JTableHeader的合并和拆分

的时候,这些类都会被重写,如果你真的需要重写这些类的时候,参考那个JTableHeader的合

并的例子就可以了.



你可能感兴趣的:(表格(表头放置组件))