JTable行可选,但单元格不可选

时间:2014-08-20 17:16:56

标签: java swing jtable row

默认情况下,JTable是可编辑的,当我们选择任何行时,我们会得到这种GUI

Demo

这里我们有两个边框,一个围绕整个行,一个围绕特定单元格,我们选择了该行。我需要外边框(整行),但不需要内部(每个单元格)边框。有没有办法实现这一目标。

1 个答案:

答案 0 :(得分:3)

我想,您需要制作自定义Border

AroundEntireRowFocusTest screenshot

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

public class AroundEntireRowFocusTest {
  String[] columnNames = {"A", "B", "C"};
  Object[][] data = {
    {"aaa", 12, "ddd"}, {"bbb", 5, "eee"}, {"CCC", 92, "fff"}
  };
  DefaultTableModel model = new DefaultTableModel(data, columnNames) {
    @Override public Class<?> getColumnClass(int column) {
      return getValueAt(0, column).getClass();
    }
  };
  public JComponent makeUI() {
    UIManager.put("Table.focusCellHighlightBorder", new DotBorder(2, 2, 2, 2));
    JTable table = new JTable(model) {
      private final DotBorder dotBorder = new DotBorder(2, 2, 2, 2);
      void updateBorderType(DotBorder border, boolean isLeadRow, int column) {
        border.type = EnumSet.noneOf(DotBorder.Type.class);
        if (isLeadRow) {
          border.type.add(DotBorder.Type.LEAD);
          if (column == 0) {
            border.type.add(DotBorder.Type.WEST);
          }
          if (column == getColumnCount() - 1) {
            border.type.add(DotBorder.Type.EAST);
          }
        }
      }
      @Override public Component prepareRenderer(
          TableCellRenderer tcr, int row, int column) {
        JComponent c = (JComponent) super.prepareRenderer(tcr, row, column);
        c.setBorder(dotBorder);
        updateBorderType(
            dotBorder, row == getSelectionModel().getLeadSelectionIndex(), column);
        return c;
      }
    };
    table.setShowGrid(false);
    table.setIntercellSpacing(new Dimension());
    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(table));
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new AroundEntireRowFocusTest().makeUI());
    frame.setSize(320, 240);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}
class DotBorder extends EmptyBorder {
  public enum Type { LEAD, WEST, EAST; }
  public EnumSet<Type> type = EnumSet.noneOf(Type.class);
  private static final BasicStroke dashed = new BasicStroke(
    1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
    10f, (new float[] {1f}), 0f);
  private static final Color DOT_COLOR = new Color(200, 150, 150);
  public DotBorder(int top, int left, int bottom, int right) {
    super(top, left, bottom, right);
  }
  @Override public boolean isBorderOpaque() {
    return true;
  }
  @Override public void paintBorder(
    Component c, Graphics g, int x, int y, int w, int h) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.translate(x, y);
    g2.setPaint(DOT_COLOR);
    g2.setStroke(dashed);
    if (type.contains(Type.WEST)) {
      g2.drawLine(0, 0, 0, h);
    }
    if (type.contains(Type.EAST)) {
      g2.drawLine(w - 1, 0, w - 1, h);
    }
    if (type.contains(Type.LEAD)) {
      if (c.getBounds().x % 2 == 0) {
        g2.drawLine(0, 0, w, 0);
        g2.drawLine(0, h - 1, w, h - 1);
      } else {
        g2.drawLine(1, 0, w, 0);
        g2.drawLine(1, h - 1, w, h - 1);
      }
    }
    g2.dispose();
  }
}