首页 > 代码库 > 《点击JTable的某一个行,在另一个JPanel显示其相对应内容的功能实现》

《点击JTable的某一个行,在另一个JPanel显示其相对应内容的功能实现》

如下图,目标是,当我点击JTable的某一行(JTable的内容来自左边的文件),在GUI的黄色框,将要显示selected行的最后一个int数据。

简短提一下为什么写这篇东西:在功能实现过程中遇到了挺多的有意义的困难,是课上老师没有讲过的,接下来一个个列出。

问题一:第一个遇到的问题是不熟悉ListSelectionListener的用法,更不知道ListSelectionModel的用法,认为ListSelectionModel是个可有可无的选择(说出来还有点不好意思呢)。

这里就讲一下ListSelectionModel的设置方法,先从table里挖出selectionMode, 然后给selectionMode加上ListSelectionListener, 最后再给予设置(我自己的版本中只允许单选),所以就是:

selectionMode = table.getSelectionModel();selectionMode.addListSelectionListener(this);selectionMode.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

问题二: 解决完第一个问题我的码看起来是这样的:

public class Main_panel extends JPanel{      
    private Research_and_InfoPanel research_and_infoPanel;    private JScrollPane scrollpane;    private ListSelectionModel listSelectionModel;    Main_panel(){      super();      BoxLayout main_layout = new BoxLayout(this, BoxLayout.X_AXIS);      setLayout(main_layout);      //creation panels      research_and_infoPanel = new Research_and_InfoPanel();      //database for TablePanel      Vector<String> column_names = new Vector<String>();      column_names.add("Title");      column_names.add("Author");      column_names.add("Year");      column_names.add("Path");      Vector<Object> data = http://www.mamicode.com/new Vector();"text-decoration: underline;"><--这是我将来想要调用的函数,属于research_and_infoPanel 也就是黄色方块    }   }}

  

可以看到,我的JTable, JScrollPanel 和 ListSelectionListener 以及他的valueChanged函数都在 Main_Panel 当中,有点混乱,所以我就想要分开Main_Panel 和其他部分元素,建了一个新的JScrollPanel子类,另开一页。效果是这样的:

public class myScrollPane extends JScrollPane implements ListSelectionListener {  private JTable table;  private ListSelectionModel selectionMode;  myScrollPane(){    super();    //database for table    Vector<String> column_names = new Vector<String>();    column_names.add("Title");    column_names.add("Author");    column_names.add("Year");    column_names.add("Path");    Vector<Object> data = http://www.mamicode.com/new Vector();"color: #888888;"> setViewportView(table);    //set scrollpane    setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS);    setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);    //set selectionMode and add Listener 
    selectionMode = table.getSelectionModel();    selectionMode.addListSelectionListener(this);    selectionMode.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);}public void valueChanged(ListSelectionEvent e) {  //rows count from zero  int selectedRow = table.getSelectedRow();  selectedRow++;  Main_panel.research_and_infoPanel.displayInfo(selectedRow);  }}

又记起了一个因为无知而浪费了不少时间的问题,就是16行,  我天真地以为只要用 add(table) 就有效,结果Table显示不出来,仔细看了下手册发现需要用setViewportview(table).

OK, 这样总体上看起来清爽整齐多了,我也“解禁”了research_and_infoPanel.displayInfo(selectedRow)函数。接下来我们看看这个函数是怎样运作的。

public class Research_and_InfoPanel extends JPanel{	private JPanel research_panel, info_panel;	private JLabel label1;	Research_and_InfoPanel(){		research_panel = new JPanel();		info_panel = new JPanel();				research_panel.setMaximumSize( new Dimension( 250, 500) );		info_panel.setMaximumSize( new Dimension( 250, 500) );				research_panel.setBackground(Color.gray);		info_panel.setBackground(Color.yellow);				BoxLayout secondary_layout = new BoxLayout(this, BoxLayout.Y_AXIS);		setLayout(secondary_layout);				label1 = new JLabel();			info_panel.add(label1);				add(research_panel);		add(info_panel);			}	public void displayInfo(int numberRow){		char filetype = proof_main.libreria.check_filetype(numberRow);		Vector<Object> extra_info = proof_main.libreria.get_info(filetype,numberRow);			switch(filetype){		case ‘E‘: {			label1.setText(extra_info.get(0).toString());		}		break;		case ‘M‘: {			label1.setText(extra_info.get(0).toString());		}		break;		case ‘V‘: {			label1.setText(extra_info.get(0).toString());		}		break;		}			}}//以下是libreria.get_info(filetype,numberRow)函数内容public Vector<Object> get_info(char filetype, int number){		Vector<Object> extra_info = new Vector<Object>();		extra_info.clear();		int bound_E = record_E.media_files.size();		int bound_M = bound_E + record_M.media_files.size();		switch(filetype){		case ‘E‘: {			extra_info.addElement(record_E.media_files.get(number-1).get_n_pages());		}		break;		case ‘M‘: {			number = number-bound_E;			extra_info.addElement(record_M.media_files.get(number-1).get_duration());			extra_info.addElement(record_M.media_files.get(number-1).get_sample_rate());		}		break;		case ‘V‘: {			number = number-bound_M;			extra_info.addElement(record_V.media_files.get(number-1).get_duration());			}		break;		}		return extra_info;	}

上面贴的码分两部分,第一部分是Research_and_InfoPanel类,里面有JLabel,故名有两个panel,但这不是我们的重点,重点在它在displayInfo中的码,因为这里面才是把数字挖出来的码。
可以看到,挖出的数据由proof_main.libreria.get_info(filetype,numberRow)提供,这里提一下我有三种不同类型的文件,是E,V和M,读者们可以当这事儿没有。而numberRow则是被鼠标或键盘选中的行,从上上个例子中用table.getSelectedRow挖出,被传啊传的直到传给libreria.get_info()。
在这篇里我就不提供别的没有重要联系的码,但是需要解释一下另有load()函数负责从文件中读取数字并装入record_E.media_files,record_M.media_files,record_V.media_files中的,大家可以想象以上第60,62,68行其实是对应的数字(在第一张图片中,相对应的数字是30)。



load()函数我以后会在未来的新文中献出。