如何解决JTable 单元格中的 JButtons 在行选择时改变形状
我的每行表格都有一个单元格(列),该单元格是一个面板,上面有 2 个按钮。 TableCellRenderer 和 TableCellEditor 已正确实现以允许渲染和编辑单元格。但是当我单击行甚至按钮时,按钮的形状会发生变化。看起来按钮的大小缩小以适应按钮文本。请参阅所附图片。
如果我设置了按钮的首选大小,那么大小似乎没有改变,但按钮文本向右移动。下面是表格单元格面板的代码。从同一个类中的 main 运行此面板,如下所示,不会显示此行为。此行为仅在将此面板用作单列表格行中的单元格时才可见。不知道要设置/更改什么属性。
public class PartitionsTableRowPanel extends javax.swing.JPanel {
/**
* Creates new form PartitionsTableRowPanel
*/
public PartitionsTableRowPanel() {
initComponents();
postinitAdjustments();
}
private void postinitAdjustments() {
// infoButton.putClientProperty("JButton.buttonType","roundRect");
// scanButton.putClientProperty("JButton.buttonType","roundRect");
//
// infoButton.addActionListener((e) -> {
// log.info("info clicked");
// });
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
setPreferredSize(new java.awt.Dimension(1000,59));
setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
jButton1.setText("Info");
add(jButton1,new org.netbeans.lib.awtextra.AbsoluteConstraints(10,20,-1,-1));
jButton2.setText("jButton2");
add(jButton2,new org.netbeans.lib.awtextra.AbsoluteConstraints(90,-1));
}// </editor-fold>
public static void main(String[] args) {
EventQueue.invokelater(() -> {
FlatDarkLaf.install();
JFrame f = new JFrame("TestProgressBar");
f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new PartitionsTableRowPanel());
f.pack();
f.setLocationRelativeto(null);
f.setVisible(true);
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
// End of variables declaration
}
下面是我的主要 JFrame 的样子:
public class MainAppWindow extends javax.swing.JFrame {
/**
* Creates new form MainWindow1
*/
public MainAppWindow() {
initComponents();
postinitAdjustments();
}
private void postinitAdjustments() {
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
northPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
partitionDetailsTable = new javax.swing.JTable();
centerPanel = new javax.swing.JPanel();
messageDetailsTextPanescrollPane = new javax.swing.JScrollPane();
messageDetailsTextPane = new javax.swing.JTextPane();
setDefaultCloSEOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Sentry disk Helper");
setName("mainFrame"); // NOI18N
setPreferredSize(new java.awt.Dimension(984,606));
northPanel.setName("northPanel"); // NOI18N
partitionDetailsTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null,null,null},{null,null}
},new String [] {
"Title 1","Title 2","Title 3","Title 4"
}
));
partitionDetailsTable.setFocusable(false);
partitionDetailsTable.setName("partitionsTable"); // NOI18N
jScrollPane1.setViewportView(partitionDetailsTable);
javax.swing.GroupLayout northPanelLayout = new javax.swing.GroupLayout(northPanel);
northPanel.setLayout(northPanelLayout);
northPanelLayout.setHorizontalGroup(
northPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(northPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1,javax.swing.GroupLayout.DEFAULT_SIZE,1048,Short.MAX_VALUE)
.addContainerGap())
);
northPanelLayout.setVerticalGroup(
northPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(northPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1,javax.swing.GroupLayout.PREFERRED_SIZE,238,javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE))
);
getContentPane().add(northPanel,java.awt.BorderLayout.norTH);
centerPanel.setBounds(new java.awt.Rectangle(2,4,0));
centerPanel.setName("centerPanel"); // NOI18N
messageDetailsTextPane.setFocusable(false);
messageDetailsTextPanescrollPane.setViewportView(messageDetailsTextPane);
javax.swing.GroupLayout centerPanelLayout = new javax.swing.GroupLayout(centerPanel);
centerPanel.setLayout(centerPanelLayout);
centerPanelLayout.setHorizontalGroup(
centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(centerPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(messageDetailsTextPanescrollPane,Short.MAX_VALUE)
.addContainerGap())
);
centerPanelLayout.setVerticalGroup(
centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,centerPanelLayout.createSequentialGroup()
.addComponent(messageDetailsTextPanescrollPane,350,Short.MAX_VALUE)
.addContainerGap())
);
getContentPane().add(centerPanel,java.awt.BorderLayout.CENTER);
getAccessibleContext().setAccessibleName("Sentery disk Helper");
setSize(new java.awt.Dimension(984,628));
setLocationRelativeto(null);
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available,stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MainAppWindow.class.getName()).log(java.util.logging.Level.SEVERE,ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainAppWindow.class.getName()).log(java.util.logging.Level.SEVERE,ex);
} catch (illegalaccessexception ex) {
java.util.logging.Logger.getLogger(MainAppWindow.class.getName()).log(java.util.logging.Level.SEVERE,ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainAppWindow.class.getName()).log(java.util.logging.Level.SEVERE,ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokelater(new Runnable() {
public void run() {
//FlatIntelliJLaf.install();
new MainAppWindow().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JPanel centerPanel;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextPane messageDetailsTextPane;
private javax.swing.JScrollPane messageDetailsTextPanescrollPane;
private javax.swing.JPanel northPanel;
private javax.swing.JTable partitionDetailsTable;
// End of variables declaration
}
添加示例代码以帮助重现问题。运行 NewJFrame1 类中的 main 以查看问题。取消注释并运行 TableRowPanel1 私有类中的 main 以查看默认的正确工作。如果我直接在 JFrame 中使用表格单元格面板组件,它工作正常。但是通过编辑器用作表格单元的相同组件显示了问题。真的需要这方面的帮助。:
/*
* To change this license header,choose License Headers in Project Properties.
* To change this template file,choose Tools | Templates
* and open the template in the editor.
*/
package com.swing.test.demo.ui;
import com.formdev.flatlaf.FlatDarkLaf;
import com.swing.test.demo.ui.components.TableRowPanel;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class NewJFrame1 extends javax.swing.JFrame {
/**
* Creates new form NewJFrame1
*/
public NewJFrame1() {
initComponents();
postinit();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
setDefaultCloSEOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null,"Title 4"
}
));
jScrollPane1.setViewportView(jTable1);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1,481,Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1,337,Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1,Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1,Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available,stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
// try {
// for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
// if ("Nimbus".equals(info.getName())) {
// javax.swing.UIManager.setLookAndFeel(info.getClassName());
// break;
// }
// }
// } catch (ClassNotFoundException ex) {
// java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE,ex);
// } catch (InstantiationException ex) {
// java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE,ex);
// } catch (illegalaccessexception ex) {
// java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE,ex);
// } catch (javax.swing.UnsupportedLookAndFeelException ex) {
// java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE,ex);
// }
//</editor-fold>
FlatDarkLaf.setup();
/* Create and display the form */
java.awt.EventQueue.invokelater(new Runnable() {
public void run() {
NewJFrame1 newJFrame1 = new NewJFrame1();
newJFrame1.setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration
private void postinit() {
List<Data> modelData = new ArrayList<>();
for (int i = 0; i < 4; i++) {
Data data = new Data();
data.value = "Data_" + i;
modelData.add(data);
}
jTable1.setDefaultRenderer(Data.class,new MyCellRenderer());
jTable1.setDefaultEditor(Data.class,new MyCellEditor());
jTable1.setModel(new MyTableModel(modelData));
jTable1.setRowHeight(52);
jTable1.revalidate();
//
}
private class Data {
String value;
}
private class MyTableModel extends AbstractTableModel {
private List<Data> data;
public MyTableModel(List<Data> data) {
this.data = data;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex,int columnIndex) {
return data.get(rowIndex);
}
@Override
public boolean isCellEditable(int rowIndex,int columnIndex) {
return true;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return Data.class;
}
}
private class MyCellRenderer implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column) {
System.out.println("fff");
return new TableRowPanel1();
}
}
private class MyCellEditor extends AbstractCellEditor implements TableCellEditor {
@Override
public Object getCellEditorValue() {
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table,int column) {
System.out.println("ddd");
return new TableRowPanel1();
}
}
private class TableRowPanel1 extends javax.swing.JPanel {
/**
* Creates new form TableRowPanel
*/
public TableRowPanel1() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the
* form. WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jButton1.setText("jButton1");
jButton2.setText("jButton2");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton2)
.addContainerGap(250,Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(14,14,14)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton1)
.addComponent(jButton2))
.addContainerGap(14,Short.MAX_VALUE))
);
}// </editor-fold>
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
// End of variables declaration
// public static void main(String[] args) {
// EventQueue.invokelater(() -> {
// FlatDarkLaf.setup();
// JFrame f = new JFrame("TestProgressBar");
// f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
// f.setContentPane(new TableRowPanel());
// f.pack();
// f.setLocationRelativeto(null);
// f.setVisible(true);
// });
//
// }
}
}
解决方法
根据源代码,根据FlatBorder
规范,表格单元格编辑器的边框插入为0。
com/formdev/flatlaf/ui/FlatBorder.java
protected boolean isCellEditor( Component c ) {
return FlatUIUtils.isCellEditor( c );
}
@Override
public Insets getBorderInsets( Component c,Insets insets ) {
// ...
if( isCellEditor( c ) ) {
// remove top and bottom insets if used as cell editor
insets.top = insets.bottom = 0;
// ...
com/formdev/flatlaf/ui/FlatUIUtils.java
public static boolean isCellEditor( Component c ) {
// check whether used in cell editor (check 3 levels up)
关于如何纠正这个问题有什么想法吗?
将单元格编辑器面板的层次结构设为三个或更多级别。
class TableRowPanel1 extends JPanel {
protected final JButton jButton1 = new JButton("jButton1");
protected final JButton jButton2 = new JButton("jButton2");
public TableRowPanel1() {
super(new BorderLayout());
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEADING));
p2.add(jButton1);
p2.add(jButton2);
JPanel p1 = new JPanel(new BorderLayout());
p1.add(p2);
add(p1);
}
}
或覆盖 FlatBorder#isCellEditor(Component c)
方法以始终返回 false
。
class TableRowPanel1 extends JPanel {
protected final JButton jButton1 = new JButton("jButton1");
protected final JButton jButton2 = new JButton("jButton2");
public TableRowPanel1() {
super(new FlowLayout(FlowLayout.LEADING));
FlatBorder border = new FlatButtonBorder() {
@Override protected boolean isCellEditor(Component c) {
return false;
}
};
jButton1.setBorder(border);
jButton2.setBorder(border);
add(jButton1);
add(jButton2);
}
}
NewJFrame2.java
import com.formdev.flatlaf.*;
import com.formdev.flatlaf.ui.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;
public class NewJFrame2 {
public Component makeUI() {
List<Data> modelData = new ArrayList<>();
for (int i = 0; i < 4; i++) {
Data data = new Data();
data.value = "Data_" + i;
modelData.add(data);
}
JTable table = new JTable(new MyTableModel(modelData));
table.setDefaultRenderer(Data.class,new MyCellRenderer());
table.setDefaultEditor(Data.class,new MyCellEditor());
table.setRowHeight(52);
JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(table));
p.add(new TableRowPanel1(),BorderLayout.SOUTH);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
FlatDarkLaf.setup();
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new NewJFrame2().makeUI());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class Data {
String value;
}
class MyTableModel extends AbstractTableModel {
private List<Data> data;
public MyTableModel(List<Data> data) {
this.data = data;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex,int columnIndex) {
return data.get(rowIndex);
}
@Override
public boolean isCellEditable(int rowIndex,int columnIndex) {
return true;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return Data.class;
}
}
class MyCellRenderer implements TableCellRenderer {
protected final TableRowPanel1 renderer = new TableRowPanel1();
@Override
public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column) {
return renderer;
}
}
class MyCellEditor extends AbstractCellEditor implements TableCellEditor {
protected final TableRowPanel1 editor = new TableRowPanel1();
@Override
public Object getCellEditorValue() {
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table,int column) {
return editor;
}
}
class TableRowPanel1 extends JPanel {
protected final JButton jButton1 = new JButton("jButton1");
protected final JButton jButton2 = new JButton("jButton2");
public TableRowPanel1() {
super(new BorderLayout());
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEADING));
p2.add(jButton1);
p2.add(jButton2);
JPanel p1 = new JPanel(new BorderLayout());
p1.add(p2);
add(p1);
}
}
// class TableRowPanel1 extends JPanel {
// protected final JButton jButton1 = new JButton("jButton1");
// protected final JButton jButton2 = new JButton("jButton2");
//
// public TableRowPanel1() {
// super(new FlowLayout(FlowLayout.LEADING));
// FlatBorder border = new FlatButtonBorder() {
// @Override protected boolean isCellEditor(Component c) {
// return false;
// }
// };
// jButton1.setBorder(border);
// jButton2.setBorder(border);
// add(jButton1);
// add(jButton2);
// }
// }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。