Java达人,请问 JTable没有选中,但是里面的 cell有选中是啥情况?如下图所示:如果要指定在 JTable 没有选中的情况下,哪个 cell有这样一个框选中,或者所有的 cell都不可以有这样一个框,代码应该怎么写?十分感谢!

解决方案 »

  1.   

    黑锅同学。。
    个人觉得JTable是没有Cell这个东西的,所以你这个需求实现起来有点难度
    坐等宝宝
      

  2.   

    你可以尝试 这个jtable focus失效 就不会有选中cell的现象了
    然后 加入 up/down/tab key的 event控制  就可以实现 行选中的操作了
      

  3.   


    jordancleft,那还能用鼠标选中 JTable吗,还有双击单元格使得光标进入单元格开始修改单元格内容的操作?
      

  4.   


    jordancleft,如果这样处理的话,鼠标还能选中 JTable 么?鼠标左键双击 JTable里的单元格,还能使光标进入单元格,然后开始可以修改单元格内容的操作么?
      

  5.   

    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    设置一下这个,这样处理一下,表格中是整行选中的,不能单独选中某一个单元格。
    表格中单元格仍然能够双击进入单元格进行修改。
      

  6.   

    那楼主你代码里是不是有这一句
    table.setCellSelectionEnabled(false);
    这句应该是跟
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    有冲突的,经过测试,有了table.setCellSelectionEnabled(false);这句
    参数是false的时候,显示效果跟楼主你的图片一模一样,如果参数是true,那允许单元格选择,那更不对了
    把table.setCellSelectionEnabled(false);这句删掉就好了
      

  7.   


    好像也还不是这样哎。我代码是这样的,我都贴出来
    public class GlobalVari extends JFrame implements KeyListener, ActionListener {
    private static final long serialVersionUID = 1L; private static double select = 1;
    private static int rowIndex = 0; public JTable table = null;
    public JScrollPane scrollPane = new JScrollPane(); public JButton buttonAdd = new JButton("Add");
    public JButton buttonDel = new JButton("Delete");
    public JButton buttonCls = new JButton("Close"); public GlobalVari() {
    init(); this.setTitle("Global Variables");
    this.setSize(new Dimension(650, 400));
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    this.setVisible(true);
    } class SymListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
    Object obj = e.getSource();
    if (obj == buttonDel) {
    buttonDel_actionPerformed(e);
    }
    }
    } private void init() {
    Vector<String> colHeader = new Vector<String>(); Vector<Vector<String>> dataVec = new Vector<Vector<String>>(); colHeader.add("Variable");
    colHeader.add("Value ");
    colHeader.add("Time "); table = new JTable(dataVec, colHeader) {
    private static final long serialVersionUID = 1L; public boolean isCellEditable(int row, int column) {
    if (column > 1) {
    return false;
    } else {
    return true;
    }
    } public void editingStopped(ChangeEvent ce) {
    super.editingStopped(ce);
    int row = getSelectedRow();
    int col = getSelectedColumn(); Object value = getValueAt(row, 0);
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    boolean exist = false;
    for (int i = 0; i < model.getRowCount(); i++) {
    if (model.getValueAt(i, 0).equals((String) value)
    && i != row) {
    exist = true;
    break;
    }
    } if (exist == true) {
    rowIndex = table.getSelectedRow();
    model.removeRow(rowIndex);
    select = 0;
    buttonDel.setEnabled(false);
    } if (select == 1 && row >= 0 && col == 1) {
    value = getValueAt(row, col);
    try {
    if (!value.equals("0")) {
    double tempVal = Double.parseDouble((String) value);
    setValueAt(BigDecimal.valueOf(tempVal)
    .stripTrailingZeros(), row, col);
    }
    } catch (Exception e) {
    setValueAt("", row, col);
    }
    } }
    }; table.getTableHeader().setPreferredSize(new Dimension(0, 20));
    table.setRowHeight(20);
    table.getSelectionModel().setSelectionMode(
    ListSelectionModel.SINGLE_SELECTION);
    table.setCellSelectionEnabled(false);
    table.getTableHeader().setReorderingAllowed(false);
    table.getTableHeader().setResizingAllowed(false);
    table.getColumnModel().getColumn(0).setPreferredWidth(95);
    table.getColumnModel().getColumn(1).setPreferredWidth(55);
    table.getColumnModel().getColumn(2).setPreferredWidth(30); DefaultTableCellRenderer right = new DefaultTableCellRenderer();
    right.setHorizontalAlignment(SwingConstants.RIGHT);
    table.getColumnModel().getColumn(1).setCellRenderer(right);
    table.getColumnModel().getColumn(2).setCellRenderer(right); ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer())
    .setHorizontalAlignment(JLabel.RIGHT); TableColumn column = table.getColumnModel().getColumn(0);
    MultiLineHeaderRenderer headerRenderer = new MultiLineHeaderRenderer(
    SwingConstants.LEFT, SwingConstants.CENTER);
    column.setHeaderRenderer(headerRenderer); column = table.getColumnModel().getColumn(0);
    JTextField textField2 = new JTextField();
    textField2.setHorizontalAlignment(JTextField.LEFT);
    column.setCellEditor(new DefaultCellEditor(textField2)); buttonAdd.setMnemonic(KeyEvent.VK_A);
    buttonAdd.setActionCommand("Add");
    buttonAdd.addActionListener(this); buttonDel.setMnemonic(KeyEvent.VK_D);
    buttonDel.setActionCommand("Delete");
    buttonDel.addActionListener(this); SymListener symListener = new SymListener();
    buttonDel.addActionListener(symListener);
    buttonDel.registerKeyboardAction(symListener,
    KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
    JComponent.WHEN_IN_FOCUSED_WINDOW); rowIndex = table.getSelectedRow();
    System.out.println("index: " + rowIndex);
    table.getSelectionModel().addListSelectionListener(
    new ListSelectionListener() {
    public void valueChanged(ListSelectionEvent e) {
    if (e.getValueIsAdjusting()) {
    rowIndex = table.getSelectedRow();
    if (rowIndex != -1) {
    System.out.println("Selected row: " + rowIndex);
    buttonDel.setEnabled(true);
    select = 1; DefaultTableModel model = (DefaultTableModel) table
    .getModel();
    System.out.println(model
    .getValueAt(rowIndex, 0));
    }
    }
    }
    }); scrollPane.setLayout(new ScrollPaneLayout());
    scrollPane.setViewportView(table);
    scrollPane.setBounds(5, 5, 515, 350);
    this.getContentPane().add(scrollPane); buttonAdd.setEnabled(true);
    buttonDel.setEnabled(false);
    buttonCls.setEnabled(true); JPanel panel = new JPanel();
    panel.setBounds(520, 5, 10, 350);
    this.getContentPane().add(panel); panel.setLayout(null);
    panel.add(buttonAdd);
    buttonAdd.setSize(100, 22);
    buttonAdd.setLocation(530, 6);
    panel.add(buttonDel);
    buttonDel.setSize(100, 22);
    buttonDel.setLocation(530, 40);
    panel.add(buttonCls);
    buttonCls.setSize(100, 22);
    buttonCls.setLocation(530, 322); buttonAdd.addMouseListener(new MouseListener() {
    public void mouseClicked(MouseEvent e) {
    } public void mousePressed(MouseEvent e) {
    if (table.getCellEditor() != null)
    table.getCellEditor().stopCellEditing();
    } public void mouseReleased(MouseEvent e) {
    } public void mouseEntered(MouseEvent e) {
    } public void mouseExited(MouseEvent e) {
    }
    }); buttonDel.addMouseListener(new MouseListener() {
    public void mouseClicked(MouseEvent e) {
    } public void mousePressed(MouseEvent e) {
    if (table.getCellEditor() != null)
    table.getCellEditor().stopCellEditing();
    } public void mouseReleased(MouseEvent e) {
    } public void mouseEntered(MouseEvent e) {
    } public void mouseExited(MouseEvent e) {
    }
    }); buttonCls.addMouseListener(new MouseListener() {
    public void mouseClicked(MouseEvent e) {
    setVisible(false);
    } public void mousePressed(MouseEvent e) {
    } public void mouseReleased(MouseEvent e) {
    } public void mouseEntered(MouseEvent e) {
    } public void mouseExited(MouseEvent e) {
    }
    }); int count = table.getColumnModel().getColumnCount();
    for (int i = 0; i < count; i++) {
    TableColumn tableColumn = table.getColumnModel().getColumn(i);
    if (tableColumn.getCellEditor() == null) {
    continue;
    }
    if (tableColumn.getCellEditor() instanceof DefaultCellEditor) {
    DefaultCellEditor dce = (DefaultCellEditor) tableColumn
    .getCellEditor();
    final Component c = dce.getComponent();
    c.addFocusListener(new FocusListener() {
    @Override
    public void focusGained(FocusEvent arg0) {
    if (c instanceof JTextComponent) {
    ((JTextComponent) c).selectAll();
    }
    } @Override
    public void focusLost(FocusEvent arg0) {
    }
    });
    }
    } this.addComponentListener(new GlobalVari_Resize(this)); this.pack();
    } public void actionPerformed(ActionEvent e) {
    buttonAdd_actionPerformed(e);
    buttonDel_actionPerformed(e);
    } public void buttonAdd_actionPerformed(ActionEvent e) {
    if ("Add".equals(e.getActionCommand())) {
    int row = table.getSelectedRow();
    int col = table.getSelectedColumn(); if (row >= 0 && col >= 0) {
    Object value = table.getValueAt(row, 0); DefaultTableModel model = (DefaultTableModel) table.getModel(); boolean exist = false; for (int i = 0; i < model.getRowCount(); i++) {
    if (model.getValueAt(i, 0).equals((String) value)
    && i != row) {
    exist = true;
    break;
    }
    } if (exist == true) {
    rowIndex = table.getSelectedRow();
    model.removeRow(rowIndex);
    select = 0;
    buttonDel.setEnabled(false);
    }
    } DefaultTableModel model = (DefaultTableModel) table.getModel();
    int rownum = table.getRowCount() + 1;
    model.addRow(new Object[] {
    "gvar" + rownum,
    "0",
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    .format(new Date()) }); buttonDel.setEnabled(true);
    row = model.getRowCount() - 1;
    col = 0;
    table.addRowSelectionInterval(row, row);
    if (table.editCellAt(row, col)) {
    Component editor = table.getEditorComponent();
    editor.requestFocusInWindow();
    Component c = editor.getComponentAt(0, 0);
    if (c != null && c instanceof JTextComponent) {
    ((JTextComponent) c).selectAll();
    }
    }
    }
    } public void buttonDel_actionPerformed(ActionEvent e) {
    if ("Delete".equals(e.getActionCommand()) || e.getSource() == buttonDel) {
    if (table.getCellEditor() != null)
    table.getCellEditor().stopCellEditing(); rowIndex = table.getSelectedRow();
    if (rowIndex >= 0) {
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.removeRow(rowIndex);
    select = 0;
    buttonDel.setEnabled(false);
    }
    }
    } public static void main(String[] args) {
    new GlobalVari();
    }
    }
      

  8.   

    这是要用到的包import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Vector;import javax.swing.DefaultCellEditor;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.KeyStroke;
    import javax.swing.ListSelectionModel;
    import javax.swing.ScrollPaneLayout;
    import javax.swing.SwingConstants;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableColumn;
      

  9.   

    这是要用到的一个类class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer {
    public MultiLineHeaderRenderer(int horizontalAlignment,
    int verticalAlignment) {
    this.horizontalAlignment = horizontalAlignment;
    this.verticalAlignment = verticalAlignment;
    switch (horizontalAlignment) {
    case SwingConstants.LEFT:
    alignmentX = (float) 0.0;
    break; case SwingConstants.CENTER:
    alignmentX = (float) 0.5;
    break; case SwingConstants.RIGHT:
    alignmentX = (float) 1.0;
    break; default:
    throw new IllegalArgumentException(
    "Illegal horizontal alignment value");
    }
    setBorder(headerBorder);
    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    setOpaque(true); background = null;
    } public void setForeground(Color foreground) {
    this.foreground = foreground;
    super.setForeground(foreground);
    } public void setBackground(Color background) {
    this.background = background;
    super.setBackground(background);
    } public void setFont(Font font) {
    this.font = font;
    } // Implementation of TableCellRenderer interface
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    removeAll();
    invalidate(); if (value == null) {
    // Do nothing if no value
    return this;
    } // Set the foreground and background colors
    // from the table header if they are not set
    if (table != null) {
    JTableHeader header = table.getTableHeader();
    if (header != null) {
    if (foreground == null) {
    super.setForeground(header.getForeground());
    } if (background == null) {
    super.setBackground(header.getBackground());
    }
    }
    } if (verticalAlignment != SwingConstants.TOP) {
    add(Box.createVerticalGlue());
    } Object[] values;
    int length;
    if (value instanceof Object[]) {
    // Input is an array - use it
    values = (Object[]) value;
    } else {
    // Not an array - turn it into one
    values = new Object[1];
    values[0] = value;
    }
    length = values.length; // Configure each row of the header using
    // a separate JLabel. If a given row is
    // a JComponent, add it directly..
    for (int i = 0; i < length; i++) {
    Object thisRow = values[i]; if (thisRow instanceof JComponent) {
    add((JComponent) thisRow);
    } else {
    JLabel l = new JLabel();
    setValue(l, thisRow, i);
    add(l);
    }
    } if (verticalAlignment != SwingConstants.BOTTOM) {
    add(Box.createVerticalGlue());
    }
    return this;
    } // Configures a label for one line of the header.
    // This can be overridden by derived classes
    protected void setValue(JLabel l, Object value, int lineNumber) {
    if (value != null && value instanceof Icon) {
    l.setIcon((Icon) value);
    } else {
    l.setText(value == null ? "" : value.toString());
    }
    l.setHorizontalAlignment(horizontalAlignment);
    l.setAlignmentX(alignmentX);
    l.setOpaque(false);
    l.setForeground(foreground);
    l.setFont(font);
    } protected int verticalAlignment; protected int horizontalAlignment; protected float alignmentX; // These attributes may be explicitly set
    // They are defaulted to the colors and attributes
    // of the table header
    protected Color foreground; protected Color background; // These attributes have fixed defaults
    protected Border headerBorder = UIManager
    .getBorder("TableHeader.cellBorder"); protected Font font = UIManager.getFont("TableHeader.font");
    }
      

  10.   

    楼主您能说一下你的这个表格的使用方法么?
    如果说新建一行,然后用户修改完Variable的值然后回车,然后再使用add按钮添加行,这个已经满足要求了。
    不过我测试出来一个bug。
    就是多添加几行,然后任选一行不是最后一行的行使用一次delete按钮,然后add按钮就废了,第一次添加能够添加,但是Variable的值与整体相比对是不正确的,而且再次点击add按钮,会删除刚添加的这一行。即使重复使用add按钮,也只会重复循环这两步操作。
    操作:
    1、使用add按钮添加3行。
    2、选择第2行,点击delete按钮删除该行。——表中剩余2行
    3、点击add按钮添加行:结果显示不正确。——表中有3行
    4、点击add按钮添加行:结果删除了刚添加的第三行。——表中剩余2行。
    5、后面再次点击add按钮,会重复3、4步。
    您说的是想解决这个问题么?我正在研读您的代码,有几个问题能问一下么?
    1、这个exist = true;中exist是判断什么的标志位呢?
    2、这个select = 0;中,double型的select始终只有1和0两种值,这个标志是做什么的?
    3、buttonDel.addActionListener(this);和buttonDel.addActionListener(symListener);这两个是什么关系的?
    4、在add按钮的侦听中,有以下一段代码
                    if (exist == true) {
                        rowIndex = table.getSelectedRow();
                        model.removeRow(rowIndex);
                        select = 0;
                        buttonDel.setEnabled(false);
                    }
    应该是导致上述bug的主要原因。
    5、您所说的“哪个 cell有这样一个框选中,或者所有的 cell都不可以有这样一个框”是想要实现什么样的操作流程呢?
      

  11.   

    这是逻辑啦。要保证 variable的唯一性...
      

  12.   


    但是貌似没有唯一成功啊触发这个bug后变量名还是重复掉了。
    那么楼主你能更详细地描述下需求么?要改的地方是当有单元格处于编辑状态的时候要按2下按钮才能实现操作的这个问题么?还是其他的。
    额,我现在已经迷茫了。
      

  13.   

    逻辑是这样的,用户按下 add按钮后,JTable 会增加一行,格式默认为 “gvar+行数, 0,创建时间”,光标落在这一行的第一个单元格里,等待用户做变量名的修改。如果这个 variable和之前的有重复,则当光标移开这个单元格后,就删除这一行。
    我的需求是:为什么在删除某些行后,JTable 是没有选中的状态,但是其中的某个单元格框周围却有一个选中的标记,就像那个图片里显示的一样。如果你这时候按下 Add按钮,不松开,然后移出去,这个单元格的框就没有了的。
      

  14.   

    这个我试了一晚上也没能复现楼主你说的bug,首先第一步删除某些行后有单元格具有选中标记这步我就操作不出来,好尴尬
    看来只好等高人来了学习学习了。
      

  15.   

    啊,没有试出来么?可以先这样,先新建两行,然后左键双击第二行的第二个单元格,这个时候光标进入该单元格,是闪烁状态。然后鼠标左键点击 Delete按钮,我所说的那个问题就出现了,JTable没有选中但是单元格有框选中的样子。这个时候如果按下 Add按钮,不松开,然后移出去,这个单元格的框就没有了的。
      

  16.   

    这,我这个还是没复现出来。。编辑状态(闪烁状态)的时候点删除,第一下是属于随便点哪都可以的解除编辑状态的效果,按钮并没有进行侦听,然后第二下再点删除,删除成功,但是却并没有出现楼主你说的那个选中框。。难道是版本问题么我是1.6的jdk
      

  17.   


    那这个和我这边不一样哎,很诧异。我这里是 1.6的JRE。