描述
開始時可以使用滑鼠單擊或鍵盤箭頭選擇一行,所選行會使用正常的行選擇顏色進行著色。
用戶可以選擇單行。
用戶可以使用鎖定按鈕呼叫的代碼鎖定所選行。通過模仿選定的行(我不確定這是否是這樣做的正確方法),鎖定本身成為可能,并且通過兩件事完成:
- 使用顏色為所選行著色
DefaultTableCellRenderer - 禁用
JTable行選擇setRowSelectionAllowed(false)
- 使用顏色為所選行著色
用戶可以使用解鎖按鈕呼叫的代碼解鎖/恢復正常選擇。解鎖簡單來說就是撤銷加鎖的步驟:
- 使用洗掉所選行的顏色
DefaultTableCellRenderer - 啟用
JTable行選擇setRowSelectionAllowed(true)<--(不起作用)
- 使用洗掉所選行的顏色
如何恢復正常的JTable行選擇?
SSCCE 中的代碼| MCVE格式
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class TableRowSelectionControl {
private JButton btnJTableSelectionLocked;
private JButton btnJTableSelectionUnlock;
private JPanel panelControl;
private JScrollPane scrollableTable;
private Integer selectedId;
private boolean lockedSelection;
private Color rowSelectionColor;
private Integer modelRow;
private JTable table;
private Object[][] data;
private JPanel createPanel() {
rowSelectionColor = new Color(184, 207, 229);
btnJTableSelectionLocked = new JButton("Lock selected row");
btnJTableSelectionLocked.setEnabled(false);
btnJTableSelectionLocked.addActionListener(new BtnAction());
btnJTableSelectionUnlock = new JButton("Unlock selection");
btnJTableSelectionUnlock.setEnabled(false);
btnJTableSelectionUnlock.addActionListener(new BtnAction());
panelControl = new JPanel();
panelControl.add(btnJTableSelectionLocked);
panelControl.add(btnJTableSelectionUnlock);
DefaultTableModel model = new DefaultTableModel(new String[]{"Id", "Name", "State"}, 0) {
// Disable cell editing
@Override
public boolean isCellEditable(int row, int column) {
// Disable cells editing.
return false;
}
};
data = new Object[][]{
{1, "Alpha", true},
{5, "Beta", false},
{3, "Gama", true},
{4, "Giga", true},
{7, "Coca", true},};
table = new JTable(model);
table.getSelectionModel().setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new RowSelectionListener());
for (Object[] d : data) {
model.addRow(d);
}
JPanel containerPanel = new JPanel(new BorderLayout());
containerPanel.setPreferredSize(new Dimension(350, 200));
scrollableTable = new JScrollPane(table);
containerPanel.add(panelControl, BorderLayout.PAGE_START);
containerPanel.add(scrollableTable, BorderLayout.CENTER);
return containerPanel;
}
private class RowSelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent event) {
// Ensure single event invoked
if (!event.getValueIsAdjusting() && !lockedSelection) {
DefaultListSelectionModel selectionModel = (DefaultListSelectionModel) event.getSource();
if (selectionModel.isSelectionEmpty()) {
// Empty selection: table row deselection occurred
btnJTableSelectionLocked.setEnabled(false);
} else {
btnJTableSelectionLocked.setEnabled(true);
int viewRow = table.getSelectedRow();
if (viewRow > -1) {
int idsColumn = 0;
modelRow = table.convertRowIndexToModel(viewRow);
Object selectedIdObject = table.getModel().getValueAt(modelRow, idsColumn);
selectedId = Integer.parseInt(selectedIdObject.toString());
}
}
}
}
}
private DefaultTableCellRenderer getRowsColorRenderer(Integer selectedId) {
DefaultTableCellRenderer renderer;
renderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component tableCellRendererComponent
= super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Integer id = (Integer) table.getModel().getValueAt(row, 0);
if (selectedId != null && id.equals(selectedId)) {
setBackground(rowSelectionColor);
setForeground(table.getForeground());
} else {
setBackground(table.getBackground());
setForeground(table.getForeground());
}
return tableCellRendererComponent;
}
};
return renderer;
}
private class BtnAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object btnClicked = e.getSource();
int columnsSize = 3;
if (btnClicked == btnJTableSelectionLocked) {
lockedSelection = true;
btnJTableSelectionLocked.setEnabled(false);
btnJTableSelectionUnlock.setEnabled(true);
table.setRowSelectionAllowed(false); // <-- Works fine.
for (int i = 0; i < columnsSize; i ) {
table.getColumnModel().getColumn(i).setCellRenderer(getRowsColorRenderer(selectedId));
}
} else if (btnClicked == btnJTableSelectionUnlock) {
lockedSelection = false;
btnJTableSelectionLocked.setEnabled(true);
btnJTableSelectionUnlock.setEnabled(false);
table.setRowSelectionAllowed(true); // <-- This line does not restore normal selection
for (int i = 0; i < columnsSize; i ) {
table.getColumnModel().getColumn(i).setCellRenderer(getRowsColorRenderer(null));
}
if (modelRow != null) {
// Enforce the same row to be selected on unloking;
// afterwords user can select any row.
table.setRowSelectionInterval(0, modelRow);
}
}
table.repaint();
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> {
TableRowSelectionControl tableRowColorControl = new TableRowSelectionControl();
JFrame frame = new JFrame("TableRowSelectionControl");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(tableRowColorControl.createPanel());
frame.pack();
frame.setVisible(true);
});
}
}
uj5u.com熱心網友回復:
你的問題在你身上 TableCellRenderer
下列...
Component tableCellRendererComponent
= super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
//...
if (selectedId != null && id.equals(selectedId)) {
setBackground(rowSelectionColor);
setForeground(table.getForeground());
} else {
setBackground(table.getBackground());
setForeground(table.getForeground());
}
正在覆寫super呼叫所做的選擇顏色。
相反,將其更改為...
DefaultTableCellRenderer renderer;
renderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component tableCellRendererComponent
= super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Integer id = (Integer) table.getModel().getValueAt(row, 0);
System.out.println("id = " id "; selectedId = " selectedId "; isSelected = " isSelected);
if (selectedId != null && id.equals(selectedId)) {
setBackground(rowSelectionColor);
setForeground(table.getForeground());
} else if (!isSelected) {
setBackground(table.getBackground());
setForeground(table.getForeground());
}
return tableCellRendererComponent;
}
};
有一件事我可能會建議是,而沒有切換的單元格渲染器(它似乎并不奏效),應用單元格渲染器表和利用的put/getClientProperty支持的JTable
private class BtnAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object btnClicked = e.getSource();
int columnsSize = 3;
if (btnClicked == btnJTableSelectionLocked) {
System.out.println("Lock");
lockedSelection = true;
btnJTableSelectionLocked.setEnabled(false);
btnJTableSelectionUnlock.setEnabled(true);
table.setRowSelectionAllowed(false); // <-- Works fine.
table.putClientProperty("selectedRowId", selectedId);
} else if (btnClicked == btnJTableSelectionUnlock) {
System.out.println("Unlock");
lockedSelection = false;
btnJTableSelectionLocked.setEnabled(true);
btnJTableSelectionUnlock.setEnabled(false);
table.setRowSelectionAllowed(true); // <-- This line does not restore normal selection
table.putClientProperty("selectedRowId", null);
}
}
}
和...
public class LockableTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Integer id = (Integer) table.getModel().getValueAt(row, 0);
Integer selectedId = (Integer) table.getClientProperty("selectedRowId");
if (selectedId != null && id.equals(selectedId)) {
setBackground(rowSelectionColor);
setForeground(table.getForeground());
} else if (!isSelected) {
setBackground(table.getBackground());
setForeground(table.getForeground());
setBorder(noFocusBorder);
}
return tableCellRendererComponent;
}
}
可運行示例...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
public class Test {
private JButton btnJTableSelectionLocked;
private JButton btnJTableSelectionUnlock;
private JPanel panelControl;
private JScrollPane scrollableTable;
private Integer selectedId;
private boolean lockedSelection;
private Color rowSelectionColor;
private Integer modelRow;
private JTable table;
private Object[][] data;
private JPanel createPanel() {
rowSelectionColor = new Color(184, 207, 229);
btnJTableSelectionLocked = new JButton("Lock selected row");
btnJTableSelectionLocked.setEnabled(false);
btnJTableSelectionLocked.addActionListener(new BtnAction());
btnJTableSelectionUnlock = new JButton("Unlock selection");
btnJTableSelectionUnlock.setEnabled(false);
btnJTableSelectionUnlock.addActionListener(new BtnAction());
panelControl = new JPanel();
panelControl.add(btnJTableSelectionLocked);
panelControl.add(btnJTableSelectionUnlock);
DefaultTableModel model = new DefaultTableModel(new String[]{"Id", "Name", "State"}, 0) {
// Disable cell editing
@Override
public boolean isCellEditable(int row, int column) {
// Disable cells editing.
return false;
}
};
data = new Object[][]{
{1, "Alpha", true},
{5, "Beta", false},
{3, "Gama", true},
{4, "Giga", true},
{7, "Coca", true},};
table = new JTable(model);
TableColumnModel columnModel = table.getColumnModel();
LockableTableCellRenderer cellRenderer = new LockableTableCellRenderer();
for (int column = 0; column < columnModel.getColumnCount(); column ) {
columnModel.getColumn(column).setCellRenderer(cellRenderer);
}
table.getSelectionModel().setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new RowSelectionListener());
for (Object[] d : data) {
model.addRow(d);
}
JPanel containerPanel = new JPanel(new BorderLayout());
containerPanel.setPreferredSize(new Dimension(350, 200));
scrollableTable = new JScrollPane(table);
containerPanel.add(panelControl, BorderLayout.PAGE_START);
containerPanel.add(scrollableTable, BorderLayout.CENTER);
return containerPanel;
}
private class RowSelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent event) {
// Ensure single event invoked
if (!event.getValueIsAdjusting() && !lockedSelection) {
DefaultListSelectionModel selectionModel = (DefaultListSelectionModel) event.getSource();
if (selectionModel.isSelectionEmpty()) {
// Empty selection: table row deselection occurred
btnJTableSelectionLocked.setEnabled(false);
} else {
btnJTableSelectionLocked.setEnabled(true);
int viewRow = table.getSelectedRow();
if (viewRow > -1) {
int idsColumn = 0;
modelRow = table.convertRowIndexToModel(viewRow);
Object selectedIdObject = table.getModel().getValueAt(modelRow, idsColumn);
selectedId = Integer.parseInt(selectedIdObject.toString());
}
}
}
}
}
private class BtnAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object btnClicked = e.getSource();
int columnsSize = 3;
if (btnClicked == btnJTableSelectionLocked) {
System.out.println("Lock");
lockedSelection = true;
btnJTableSelectionLocked.setEnabled(false);
btnJTableSelectionUnlock.setEnabled(true);
table.setRowSelectionAllowed(false); // <-- Works fine.
table.putClientProperty("selectedRowId", selectedId);
} else if (btnClicked == btnJTableSelectionUnlock) {
System.out.println("Unlock");
lockedSelection = false;
btnJTableSelectionLocked.setEnabled(true);
btnJTableSelectionUnlock.setEnabled(false);
table.setRowSelectionAllowed(true); // <-- This line does not restore normal selection
table.putClientProperty("selectedRowId", null);
}
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> {
Test tableRowColorControl = new Test();
JFrame frame = new JFrame("TableRowSelectionControl");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(tableRowColorControl.createPanel());
frame.pack();
frame.setVisible(true);
});
}
public class LockableTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Integer id = (Integer) table.getModel().getValueAt(row, 0);
Integer selectedId = (Integer) table.getClientProperty("selectedRowId");
if (selectedId != null && id.equals(selectedId)) {
setBackground(rowSelectionColor);
setForeground(table.getForeground());
} else if (!isSelected) {
setBackground(table.getBackground());
setForeground(table.getForeground());
setBorder(noFocusBorder);
}
return tableCellRendererComponent;
}
}
}
uj5u.com熱心網友回復:
外觀極好的答案從MadProgrammer。在這里,我只是在很少更新的情況下使用它;供我參考和未來的訪客。
不使用某些列值作為唯一識別符號來跟蹤所選行,而是使用
TableModel行索引;那是行內容不可知的解決方案。當用戶解鎖所選行時;保持選中相同的選定行,以獲得良好的用戶體驗。
代碼:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
public class TableRowSelectionControl {
private JButton btnJTableSelectionLock;
private JButton btnJTableSelectionUnlock;
private JPanel panelControl;
private JScrollPane scrollableTable;
private boolean lockedSelection;
private Color rowSelectionColor;
private final String selectedRowKey = "selectedRow";
private Integer selectedModelRow;
private Integer oldSelectedModelRow;
private JTable table;
private Object[][] data;
private JPanel createPanel() {
rowSelectionColor = new Color(184, 207, 229);
btnJTableSelectionLock = new JButton("Lock selected row");
btnJTableSelectionLock.setEnabled(false);
btnJTableSelectionLock.addActionListener(new BtnAction());
btnJTableSelectionUnlock = new JButton("Unlock selection");
btnJTableSelectionUnlock.setEnabled(false);
btnJTableSelectionUnlock.addActionListener(new BtnAction());
panelControl = new JPanel();
panelControl.add(btnJTableSelectionLock);
panelControl.add(btnJTableSelectionUnlock);
DefaultTableModel model = new DefaultTableModel(new String[]{"Id", "Name", "State"}, 0) {
// Disable cell editing
@Override
public boolean isCellEditable(int row, int column) {
// Disable cells editing.
return false;
}
};
data = new Object[][]{
{1, "Alpha", true},
{5, "Beta", false},
{3, "Gamma", true},
{4, "Giga", true},
{7, "Coca", true},};
table = new JTable(model);
TableColumnModel columnModel = table.getColumnModel();
LockableTableCellRenderer cellRenderer = new LockableTableCellRenderer();
for (int column = 0; column < columnModel.getColumnCount(); column ) {
columnModel.getColumn(column).setCellRenderer(cellRenderer);
}
table.getSelectionModel().setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new RowSelectionListener());
for (Object[] d : data) {
model.addRow(d);
}
JPanel containerPanel = new JPanel(new BorderLayout());
containerPanel.setPreferredSize(new Dimension(350, 200));
scrollableTable = new JScrollPane(table);
containerPanel.add(panelControl, BorderLayout.PAGE_START);
containerPanel.add(scrollableTable, BorderLayout.CENTER);
return containerPanel;
}
private class RowSelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent event) {
// Ensure single event invoked
if (!event.getValueIsAdjusting() && !lockedSelection) {
DefaultListSelectionModel selectionModel = (DefaultListSelectionModel) event.getSource();
if (selectionModel.isSelectionEmpty()) {
// Empty selection: table row deselection occurred
btnJTableSelectionLock.setEnabled(false);
} else {
btnJTableSelectionLock.setEnabled(true);
int viewRow = table.getSelectedRow();
if (viewRow > -1) {
selectedModelRow = table.convertRowIndexToModel(viewRow);
}
}
}
}
}
private class BtnAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object btnClicked = e.getSource();
if (btnClicked == btnJTableSelectionLock) {
System.out.println("Lock");
lockedSelection = true;
btnJTableSelectionLock.setEnabled(false);
btnJTableSelectionUnlock.setEnabled(true);
table.setRowSelectionAllowed(false);
oldSelectedModelRow = selectedModelRow;
table.putClientProperty(selectedRowKey, selectedModelRow);
} else if (btnClicked == btnJTableSelectionUnlock) {
System.out.println("Unlock");
lockedSelection = false;
btnJTableSelectionLock.setEnabled(true);
btnJTableSelectionUnlock.setEnabled(false);
table.setRowSelectionAllowed(true);
table.putClientProperty(selectedRowKey, null);
table.setRowSelectionInterval(0, oldSelectedModelRow);
}
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> {
TableRowSelectionControl tableRowColorControl = new TableRowSelectionControl();
JFrame frame = new JFrame("TableRowSelectionControl");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(tableRowColorControl.createPanel());
frame.pack();
frame.setVisible(true);
});
}
public class LockableTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Integer renderedRow = table.convertRowIndexToModel(row);
Integer selectedRow = (Integer) table.getClientProperty(selectedRowKey);
if (selectedRow != null && renderedRow.equals(selectedRow)) {
setBackground(rowSelectionColor);
setForeground(table.getForeground());
} else if (!isSelected) {
setBackground(table.getBackground());
setForeground(table.getForeground());
setBorder(noFocusBorder);
}
return tableCellRendererComponent;
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/391088.html
上一篇:當按下ENTER時,按鈕單擊未擊中OnPost()方法
下一篇:如何使用時間跨度來倒計時分鐘?
