java - JTable 行可选择但单元格不可选择

标签 java swing jtable row

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

Demo

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

最佳答案

我想,您需要制作一个自定义的边框

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();
  }
}

关于java - JTable 行可选择但单元格不可选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25410736/

相关文章:

java - boolean 值 - 它应该停止时却没有停止(JAVA)

java - 由于 Java 9 HashMap.computeIfAbsent() 在尝试内存递归函数结果时抛出 ConcurrentModificationException

java - Jframe 内容不显示

java - 从 "Filthy Rich Clients"开始理解Swing代码

java - JTable、TableModel 等的复杂使用

java - jdbc的registerOutParameter中的sqlType是什么意思?

java - JiBX 绑定(bind) - 根对象扩展对象

java - 在对话框中将字符串转换为 double

Java JTable 展开折叠行为

swing - JTable + TableModel 缓存获取事件以进行延迟实例化?