2013-05-05 36 views
0

我想建一个表,其中包括JComboBoxes作为渲染器和编辑器两个组件。这大多工作正常,但有两件事我似乎无法解决。细胞之间可用性功能JComboBox的内JTable中

  1. Tab键应该做的JComboBox活跃
  2. 点击下拉箭头应立即打开选项列表

关于1,编辑组合应该将嵌入文本字段中的焦点,固定组合应允许向下箭头打开选项列表。

关于2,我觉得这取决于什么其他细胞是当前活动有时工作,但其他时间我需要双击。我无法使这种行为保持一致。

为了方便起见我已经包括其中(I相信)使用用于内JTable中嵌入JComboBoxes建议的方法的明显例子。

谢谢你的建设性意见。

import java.awt.Component; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public class TableCombos 
{ 
    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame("Frame"); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     AbstractTableModel model = new DefaultTableModel() 
     { 
      String[] columnHeaders = new String[]{"label", "combo-edit", "combo-fixed"}; 
      Class<?>[] columnClasses = new Class<?>[]{String.class, Double.class, Double.class}; 
      List<Object[]> data = new ArrayList<>(); 
      { 
       data.add(new Object[]{"row 1", 1.0d, 2.0d}); 
       data.add(new Object[]{"row 2", 2.0d, 3.0d}); 
      } 

      @Override 
      public int getColumnCount() 
      { 
       return columnHeaders.length; 
      } 

      @Override 
      public boolean isCellEditable(int row, int column) 
      { 
       return column != 0; 
      } 

      @Override 
      public int getRowCount() 
      { 
       if (data == null) // race condition 
        return 0; 
       return data.size(); 
      } 

      @Override 
      public Object getValueAt(int row, int column) 
      { 
       return data.get(row)[column]; 
      } 

      @Override 
      public void setValueAt(Object aValue, int row, int column) 
      { 
       data.get(row)[column] = aValue; 
      } 

      @Override 
      public Class<?> getColumnClass(int column) 
      { 
       return columnClasses[column]; 
      } 

      @Override 
      public String getColumnName(int column) 
      { 
       return columnHeaders[column]; 
      } 
     }; 

     JTable table = new JTable(model); 
     table.setSurrendersFocusOnKeystroke(true); 

     TableColumn c1 = table.getColumnModel().getColumn(1); 
     TableColumn c2 = table.getColumnModel().getColumn(2); 

     JComboBox<Double> editorComboEditable = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d}); 
     editorComboEditable.setEditable(true); 
     c1.setCellEditor(new DefaultCellEditor(editorComboEditable)); 
     c2.setCellEditor(new DefaultCellEditor(new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d}))); 

     final JComboBox<Double> rendererComboEditable = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d}); 
     rendererComboEditable.setEditable(true); 
     final JComboBox<Double> rendererComboFixed = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d}); 
     c1.setCellRenderer(new TableCellRenderer() 
     { 
      @Override 
      public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
      { 
       rendererComboEditable.setSelectedItem(value); 
       return rendererComboEditable; 
      } 
     }); 
     c2.setCellRenderer(new TableCellRenderer() 
     { 
      @Override 
      public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
      { 
       rendererComboFixed.setSelectedItem(value); 
       return rendererComboFixed; 
      } 
     }); 

     frame.getContentPane().add(new JScrollPane(table)); 

     frame.pack(); 
     frame.setVisible(true); 
    } 
} 
+2

*“我已经包含了一个明显的例子” *很好的例子。不过,要更好地解决(包括)进口问题。我通常发现所有'java.awt','java.awt.event'和'javax.swing'都可以在没有冲突的情况下导入,所以这只需要再多3行代码就可以编译一个GUI示例,并且不会出现ifs或buts'.. – 2013-05-05 03:44:49

+0

谢谢@AndrewThompson我试图保持简短。已包括进口和类别十二月。 – pstanton 2013-05-05 03:57:13

+0

嗯..'列表 data = new ArrayList <>();'这是一个Java 7的东西,你可以省略第二种类型?例如。 'List data = new ArrayList ();'在Java 6编译。我在这里得到4个编译错误,用于4个简短形式的语句。 – 2013-05-05 04:02:04

回答

3

你的问题都通过重写DefaultCellEditor#isCellEditable方法和返回true

您可能需要设置JTable#setSurrendersFocusOnKeystroke为true以及

更新

简短的回答是可以解决“这很混乱”。长的答案是“这是非常混乱”

我做了一个“连续的编辑”过程中的某些时候能回来。基本上,我推翻了输入标签键绑定。

什么我都基本上停止任何活动单元格编辑器,请注意当前单元格,然后试图寻找下一个可编辑的单元格,如果需要,围绕循环回到开始(电池为0x0)。

当我发现一个可编辑的单元格,我叫JTable#esitCellAt开始编辑的单元格。

为了让弹出可见当细胞开始编辑,您将需要重写JComboBoxaddNotify方法,并使用SwingUtilities#invokeLater,设置可见弹出

+0

(XxxCell)编辑器。setClickCountToStart(2); – mKorbel 2013-05-05 07:23:13

+0

@mkorbel这是一个很好的补充,但是如果你从isCelleEditable返回true,那么它并不重要,因为任何键盘或鼠标事件都将开始编辑;) – MadProgrammer 2013-05-05 07:37:23

+0

@MadProgrammer谢谢我会试试这个并尽快报告回来 – pstanton 2013-05-05 07:37:29