Java核心技术卷2 程序清单6-7

package tableRowColumn;

import java.awt.*;
import java.util.*;

import javax.swing.*;
import javax.swing.table.*;

/**
 * This frame contains a table of planet data.
 */
public class PlanetTableFrame extends JFrame
{
   private static final int DEFAULT_WIDTH = 600;
   private static final int DEFAULT_HEIGHT = 500;

   public static final int COLOR_COLUMN = 4;
   public static final int IMAGE_COLUMN = 5;

   private JTable table;
   private HashSet<Integer> removedRowIndices;
   private ArrayList<TableColumn> removedColumns;   
   private JCheckBoxMenuItem rowsItem;
   private JCheckBoxMenuItem columnsItem;
   private JCheckBoxMenuItem cellsItem;

   private String[] columnNames = { "Planet", "Radius", "Moons", "Gaseous", "Color", "Image" };

   private Object[][] cells = {
         { "Mercury", 2440.0, 0, false, Color.YELLOW, 
            new ImageIcon(getClass().getResource("Mercury.gif")) },
         { "Venus", 6052.0, 0, false, Color.YELLOW, 
            new ImageIcon(getClass().getResource("Venus.gif")) },
         { "Earth", 6378.0, 1, false, Color.BLUE, 
            new ImageIcon(getClass().getResource("Earth.gif")) },
         { "Mars", 3397.0, 2, false, Color.RED, 
            new ImageIcon(getClass().getResource("Mars.gif")) },
         { "Jupiter", 71492.0, 16, true, Color.ORANGE, 
            new ImageIcon(getClass().getResource("Jupiter.gif")) },
         { "Saturn", 60268.0, 18, true, Color.ORANGE, 
            new ImageIcon(getClass().getResource("Saturn.gif")) },
         { "Uranus", 25559.0, 17, true, Color.BLUE, 
            new ImageIcon(getClass().getResource("Uranus.gif")) },
         { "Neptune", 24766.0, 8, true, Color.BLUE, 
            new ImageIcon(getClass().getResource("Neptune.gif")) },
         { "Pluto", 1137.0, 1, false, Color.BLACK, 
            new ImageIcon(getClass().getResource("Pluto.gif")) } };

   public PlanetTableFrame()
   {
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

      TableModel model = new DefaultTableModel(cells, columnNames)
         {
            public Class<?> getColumnClass(int c)
            {
               return cells[0][c].getClass();
            }
         };

      table = new JTable(model);
      
      table.setRowHeight(100);
      table.getColumnModel().getColumn(COLOR_COLUMN).setMinWidth(250);
      table.getColumnModel().getColumn(IMAGE_COLUMN).setMinWidth(100);
      
      final TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
      table.setRowSorter(sorter);
      sorter.setComparator(COLOR_COLUMN, Comparator.comparing(Color::getBlue)
         .thenComparing(Color::getGreen).thenComparing(Color::getRed));
      sorter.setSortable(IMAGE_COLUMN, false);
      add(new JScrollPane(table), BorderLayout.CENTER);

      removedRowIndices = new HashSet<>();
      removedColumns = new ArrayList<>();

      final RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>()
      {
         public boolean include(Entry<? extends TableModel, ? extends Integer> entry)
         {
            return !removedRowIndices.contains(entry.getIdentifier());
         } 
      };
      
      // create menu

      JMenuBar menuBar = new JMenuBar();
      setJMenuBar(menuBar);

      JMenu selectionMenu = new JMenu("Selection");
      menuBar.add(selectionMenu);

      rowsItem = new JCheckBoxMenuItem("Rows");
      columnsItem = new JCheckBoxMenuItem("Columns");
      cellsItem = new JCheckBoxMenuItem("Cells");

      rowsItem.setSelected(table.getRowSelectionAllowed());
      columnsItem.setSelected(table.getColumnSelectionAllowed());
      cellsItem.setSelected(table.getCellSelectionEnabled());

      rowsItem.addActionListener(event ->
         {
            table.clearSelection();
            table.setRowSelectionAllowed(rowsItem.isSelected());
            updateCheckboxMenuItems();
         });
      selectionMenu.add(rowsItem);

      columnsItem.addActionListener(event ->
         {
            table.clearSelection();
            table.setColumnSelectionAllowed(columnsItem.isSelected());
            updateCheckboxMenuItems();
         });
      selectionMenu.add(columnsItem);

      cellsItem.addActionListener(event ->
         {
            table.clearSelection();
            table.setCellSelectionEnabled(cellsItem.isSelected());
            updateCheckboxMenuItems();
         });
      selectionMenu.add(cellsItem);

      JMenu tableMenu = new JMenu("Edit");
      menuBar.add(tableMenu);

      JMenuItem hideColumnsItem = new JMenuItem("Hide Columns");
      hideColumnsItem.addActionListener(event ->
         {
            int[] selected = table.getSelectedColumns();
            TableColumnModel columnModel = table.getColumnModel();

            // remove columns from view, starting at the last
            // index so that column numbers aren't affected

            for (int i = selected.length - 1; i >= 0; i--)
            {
               TableColumn column = columnModel.getColumn(selected[i]);
               table.removeColumn(column);

               // store removed columns for "show columns" command

               removedColumns.add(column);
            }
         });
      tableMenu.add(hideColumnsItem);

      JMenuItem showColumnsItem = new JMenuItem("Show Columns");
      showColumnsItem.addActionListener(event ->
         {
            // restore all removed columns
            for (TableColumn tc : removedColumns)
               table.addColumn(tc);
            removedColumns.clear();
         });
      tableMenu.add(showColumnsItem);
      
      JMenuItem hideRowsItem = new JMenuItem("Hide Rows");
      hideRowsItem.addActionListener(event ->
         {
            int[] selected = table.getSelectedRows();
            for (int i : selected)
               removedRowIndices.add(table.convertRowIndexToModel(i));
            sorter.setRowFilter(filter);
         });
      tableMenu.add(hideRowsItem);

      JMenuItem showRowsItem = new JMenuItem("Show Rows");
      showRowsItem.addActionListener(event ->
         {
            removedRowIndices.clear();
            sorter.setRowFilter(filter);
         });
      tableMenu.add(showRowsItem);
      
      JMenuItem printSelectionItem = new JMenuItem("Print Selection");
      printSelectionItem.addActionListener(event ->
         {
            int[] selected = table.getSelectedRows();
            System.out.println("Selected rows: " + Arrays.toString(selected));
            selected = table.getSelectedColumns();
            System.out.println("Selected columns: " + Arrays.toString(selected));
         });
      tableMenu.add(printSelectionItem);      
   }

   private void updateCheckboxMenuItems()
   {
      rowsItem.setSelected(table.getRowSelectionAllowed());
      columnsItem.setSelected(table.getColumnSelectionAllowed());
      cellsItem.setSelected(table.getCellSelectionEnabled());
   }
}

该代码段定义了一个扩展了JFrame的类的PlanetTableFrame,这个frame绘制了一个包含行星数据的表格。这里新的类有HashSet<Integer>, ArrayList<TableColumn>以及JCheckBoxMenuItem。


扩展了JFrame的类最重要的函数就是它的构造函数,

首先是设置的一个窗口大小,然后建立一个表格模型(根据一个Object[][]和一个String[]构造的一个DefaultTableModel),

一般X是一个接口,AbstractX为实现了这个接口的抽象类,DefaultX则是可以用来直接使用的默认类,这里的X就是TableModel。

这里重写了getColumnClass方法,返回的cells[0][c]的getClass()方法返回的Class对象。

然后使用这个model构造的一个JTable。

设置行的高度为100,将COLOR_COLUMN行(index为4)的列的最小宽度设置为250,将IMAGE_COLUMN列的最小宽度设置为100。

 

设置一个新的TableRowSorter,使用TableRowSorter的setComparator方法来设置一个比较器(设置的是COLOR列的比较器),该比较器先根据getBlue的返回值来比较, 再根据getGreen的返回值进行比较,最后根据getRed的返回值进行比较。设置IMGAE列为可排序的,将JScrollPane放在frame的中间,

 

用相应地默认构造函数构造一个HashSet<>和一个ArrayList<>,

接着建立了一个RowFilter,这里重写了一个include函数,这个函数的核心就是看HashSet中是否含有entry.getIndentifier()(这个方法返回的是该行在model中的标识符,对于一个TableModel来说,就是行的索引),如果不包含,则保留,包含则不保留。


最后一个部分是创建一个menu,将这个JMenuBar设置为这个Frame的菜单栏,

然后设置一个标签为Selection的JMenu,将这个JMenu放到菜单栏中,接着创建可以选择或取消选择的菜单项,标签为Rows、Columns和Cells。

如果行可选,则将rowsItem设置为选定,

如果列可选,将columnItem设置为选定

如果行和列可选,则将cellsItem设置为选定

给rowsItem增加一个侦听器,这个侦听器首先取消所有选定的行和列,然后根据rowsItem是否被选定设置是否允许行选择,最后调用updateCheckboxMenuItems()函数。

columnsItem和cellsItem采用相同的的方式添加侦听器。

然后在JMenuBar上加上一个标签为“Edit”的JMenu,在Edit下添加一个标签为Hide Columns的JMenuItem,这个Hide Columns的侦听器:

该侦听器首先获得所有选定列的索引,是一个int[],然后获得这个JTable的TableColumnModel,然后使用一个for循环从视图中删除列,从最后一个索引开始,这样列号就不会受到影响。

(for循环中,总共使用的循环次数为int[]数组的长度,先得到相应列的TableColumn,然后使用JTable的removeColumn方法删除负责显示它的TableColumn。将被删除列的TableColumn存储在ArrayList<TableColumn>中。)

在edit(一个JMenu)下再创建一个Show Columns(一个JMenuItem),这个按钮的侦听器用于恢复所有被清除列,

在edit下再创建一个JMenuItem: Hide Rows用于隐藏列。这个循环遍历int[]中的数,隐藏行需要对行进行过滤,需要过滤的行存在removedRowIndices(一个HashSet<Integer>),这种处理过程称为过滤(filtering),要想激活过滤机制,需要设置RowFilter,然后调用TableRowSorter的setRowFilter方法。这个方法设置了sorter的filter方法,这个方法会触发一个排序事件。

 

添加的Show Rows按钮(一个JMenuItem)就是将removedRowIndices中的所有元素都删除,这样就不过滤了。最后是添加一个Print Seclection,作用是打印出选择的行和列。

最后一个函数是updateCheckboxMenuItems(),根据Jtable行、列、单元格是否能被选中,设置MenuItem的状态。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值