这是要用到的一个类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"); }
个人觉得JTable是没有Cell这个东西的,所以你这个需求实现起来有点难度
坐等宝宝
然后 加入 up/down/tab key的 event控制 就可以实现 行选中的操作了
jordancleft,那还能用鼠标选中 JTable吗,还有双击单元格使得光标进入单元格开始修改单元格内容的操作?
jordancleft,如果这样处理的话,鼠标还能选中 JTable 么?鼠标左键双击 JTable里的单元格,还能使光标进入单元格,然后开始可以修改单元格内容的操作么?
设置一下这个,这样处理一下,表格中是整行选中的,不能单独选中某一个单元格。
表格中单元格仍然能够双击进入单元格进行修改。
table.setCellSelectionEnabled(false);
这句应该是跟
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
有冲突的,经过测试,有了table.setCellSelectionEnabled(false);这句
参数是false的时候,显示效果跟楼主你的图片一模一样,如果参数是true,那允许单元格选择,那更不对了
把table.setCellSelectionEnabled(false);这句删掉就好了
好像也还不是这样哎。我代码是这样的,我都贴出来
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();
}
}
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;
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");
}
如果说新建一行,然后用户修改完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都不可以有这样一个框”是想要实现什么样的操作流程呢?
但是貌似没有唯一成功啊触发这个bug后变量名还是重复掉了。
那么楼主你能更详细地描述下需求么?要改的地方是当有单元格处于编辑状态的时候要按2下按钮才能实现操作的这个问题么?还是其他的。
额,我现在已经迷茫了。
我的需求是:为什么在删除某些行后,JTable 是没有选中的状态,但是其中的某个单元格框周围却有一个选中的标记,就像那个图片里显示的一样。如果你这时候按下 Add按钮,不松开,然后移出去,这个单元格的框就没有了的。
看来只好等高人来了学习学习了。
那这个和我这边不一样哎,很诧异。我这里是 1.6的JRE。