【发布时间】:2018-05-08 23:46:50
【问题描述】:
我需要一个 UI 来一遍又一遍地收集类似的数据,最好将其描述为批处理条目。要输入批处理,我需要一个滚动窗格来调整用户输入的任何数据大小。为了顺利完成这项工作,我依靠附加到 jscrollpane 的 jtable,并将行作为 jpanel。我在使用此解决方案时遇到了一些麻烦,即
- 我不知道如何访问我的 jpanel 中的文本字段
- 我不知道如何在我的 jtable 上添加更多 jpanel 作为行。
我可以补充一点,在尝试将许多 jpanel 一次又一次地添加到一个 jscrollpane 之后,我跳到了这个解决方案(这可能不一定是最好的),但这并不奏效。这个替代方案失败,因为似乎通过 setviewportview 添加 jpanel 并不是为了接受新面板来扩展视图。相同的变体是 一个 jpanel 附加到一个滚动窗格,然后添加 许多 jpanel在附加到滚动窗格的主面板上,但视图没有展开并且滚动窗格保持不变。我已经检查了oracle's scrollpane tutorial并看到了客户端的动态变化以及如何重新验证客户端但不知道如何这将适用于我添加新 jpanel 的情况(除非我将它们添加到一个 jpanel 上,我会在添加新 jpanel 时不断设置新的客户首选大小。)
注意:
- 我不断添加的 jpanel 并不是真正新的,因为我正在对其进行迭代。
- 我尝试过的另一个第三个解决方案是使用灵活的网格布局,它的行是用户可以选择的变量“x”,并且可以添加多个“x”jpanel,问题是,这是主要问题,滚动窗格不能很好地允许扩展,因此它也没有适应新的视图。
- 请注意,我需要的滚动窗格不应附加到 JFrame,而应附加到 JFrame 内的内部视图(如仅在 borderLayout UI 中的 North 或 Center 的滚动窗格)。
- 我知道作为一行的 jpanel 可以替换为普通行,其中行上的每个单元格都可以充当 jtextfield、jlabel 或我需要的任何组件,但这种方法是针对特定需要制作的JTable 看起来像一个实际的物理文档。
如何制作一个可以动态扩展以添加 jpanels 的良好滚动窗格?
下面的代码显示了两次添加 jpanels 以希望扩展滚动窗格的尝试,但都失败了。
解决方案一将每个单元格呈现为 jpanel,但我无法访问 jpanel 上的文本字段,因此我无法从用户那里获取数据,也无法添加另一行来创建批处理。
public class JTablePanelRow extends JFrame implements ActionListener{
JButton addRow = new JButton("Add Row");
JTable table = new JTable();
JScrollPane spane = new JScrollPane();
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel panelRow = new JPanel();
JLabel lblName = new JLabel("NAME");
JTextField txName = new JTextField();
JLabel lblAge = new JLabel("AGE");
JTextField txAge = new JTextField();
TblModel tblmodel = new TblModel();
public static void main(String[] args) {
JTablePanelRow tblPane = new JTablePanelRow();
tblPane.init();
}
void init(){
panelRow.setLayout(new GridLayout(2,2,4,4));
panelRow.add(lblName);
panelRow.add(txName);
panelRow.add(lblAge);
panelRow.add(txAge);
table.setModel(tblmodel);
table.setRowHeight(50);
table.getColumn("A").setCellRenderer(new PanelRenderer(panelRow));
spane.setViewportView(table);
addRow.addActionListener(this);
mainPanel.add(addRow,"North");
mainPanel.add(spane,"Center");
this.getContentPane().add(mainPanel);
this.setVisible(true);
this.setSize(new Dimension(400,500));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==addRow){
tblmodel.addNewRow();
}
}
}
class TblModel extends AbstractTableModel{
@Override
public int getRowCount() {
return 1;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return "";
}
public void addNewRow(){
//how to add the jpanel again
}
}
class PanelRenderer extends DefaultTableCellRenderer{
JPanel entryPn = new JPanel();
public PanelRenderer(JPanel entryPn){
this.entryPn = entryPn;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
entryPn.setPreferredSize(new Dimension(200,50));
entryPn.setBackground(Color.pink);
return entryPn;}
}
解决方案二尝试通过灵活的网格布局添加 jpanel,但 jpanel 未添加或不可滚动。
public class GridLayoutTrick extends JFrame{
JPanel mainPanel = new JPanel(new BorderLayout());
JScrollPane scroll = new JScrollPane();
JPanel entryPanel = new JPanel();
JPanel rowPanel = new JPanel();
int batchNumber = 10;
JPanel northPanel = new JPanel();
public static void main(String[] args) {
GridLayoutTrick glt = new GridLayoutTrick();
glt.init();
}
void init(){
rowPanel.setBackground(Color.PINK);
rowPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK,5));
rowPanel.setPreferredSize(new Dimension(100,50));
entryPanel.setLayout(new GridLayout(batchNumber,1,4,4));
for(int i = 0;i < batchNumber;i++){
entryPanel.add(rowPanel);
}
entryPanel.setBackground(Color.BLUE);
scroll.setViewportView(entryPanel);
mainPanel.add(northPanel,"North");
mainPanel.add(scroll,"Center");
this.getContentPane().add(mainPanel);
this.setVisible(true);
this.setSize(new Dimension(400,400));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
【问题讨论】:
-
为什么不让表格可编辑?
TableModel应该携带每一行的数据,然后可以将其拆分为单独的列 -
另一种选择可能是有一个“输入”窗格,当用户点击并添加/更新按钮时,会将数据添加到表模型中
-
@MadProgrammer 你的意思是让 jtable 单元格可编辑吗?我在 TableModel 中通过覆盖 isCellEditable 方法将其设置为 true 来做到这一点,但我很震惊地意识到,一旦我单击单元格,就无法选择 jpanel 上的文本字段,它就像一个 jtable 行!!!至于您建议的带有添加/更新按钮的“输入”窗格的替代方案,事实上,这就是我所拥有的,正在努力的是 scrollpane 以允许用户可以看到的批处理条目整批而不是“零碎”条目..
-
问题是,我会让每个单元格负责编辑特定字段,而不是让面板中包含多个字段