I have JCheckBox in JComboBox code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CheckCombo implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JComboBox cb = (JComboBox)e.getSource();
CheckComboStore store = (CheckComboStore)cb.getSelectedItem();
CheckComboRenderer ccr = (CheckComboRenderer)cb.getRenderer();
ccr.checkBox.setSelected((store.state = !store.state));
}
private JPanel getContent()
{
String[] ids = { "north", "west", "south", "east", "ALL" };
Boolean[] values =
{
Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE
};
CheckComboStore[] stores = new CheckComboStore[ids.length];
for(int j = 0; j < ids.length; j++)
stores[j] = new CheckComboStore(ids[j], values[j]);
JComboBox combo = new JComboBox(stores);
combo.setRenderer(new CheckComboRenderer());
combo.addActionListener(this);
JPanel panel = new JPanel();
panel.add(combo);
return panel;
}
public static void main(String[] args)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new CheckCombo().getContent());
f.setSize(300,160);
f.setLocation(200,200);
f.setVisible(true);
}
}
/** adapted from comment section of ListCellRenderer api */
class CheckComboRenderer implements ListCellRenderer
{
JCheckBox checkBox;
public CheckComboRenderer()
{
checkBox = new JCheckBox();
}
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
CheckComboStore store = (CheckComboStore)value;
checkBox.setText(store.id);
checkBox.setSelected(((Boolean)store.state).booleanValue());
checkBox.setBackground(isSelected ? Color.red : Color.white);
checkBox.setForeground(isSelected ? Color.white : Color.black);
return checkBox;
}
}
class CheckComboStore
{
String id;
Boolean state;
public CheckComboStore(String id, Boolean state)
{
this.id = id;
this.state = state;
}
}
How can I check all box after check ALL and 'de'check(false)
When you select "ALL" you have all selected, when you deselect "ALL" you have all deselected. Try out and play with it.
public class CheckCombo implements ActionListener {
JComboBox combo = null;
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
CheckComboStore store = (CheckComboStore) cb.getSelectedItem();
CheckComboRenderer ccr = (CheckComboRenderer) cb.getRenderer();
ccr.checkBox.setSelected((store.state = !store.state));
if (store.id.equals("ALL")){
for (int i = 0; i < combo.getItemCount(); i++){
((CheckComboStore)combo.getItemAt(i)).state = ccr.checkBox.isSelected();
}
}
}
private JPanel getContent() {
String[] ids = { "north", "west", "south", "east", "ALL" };
Boolean[] values = { Boolean.TRUE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE };
CheckComboStore[] stores = new CheckComboStore[ids.length];
for (int j = 0; j < ids.length; j++)
stores[j] = new CheckComboStore(ids[j], values[j]);
combo = new JComboBox(stores);
combo.setRenderer(new CheckComboRenderer());
combo.addActionListener(this);
JPanel panel = new JPanel();
panel.add(combo);
return panel;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new CheckCombo().getContent());
f.setSize(300, 160);
f.setLocation(200, 200);
f.setVisible(true);
}
}
/** adapted from comment section of ListCellRenderer api */
class CheckComboRenderer implements ListCellRenderer {
JCheckBox checkBox;
public CheckComboRenderer() {
checkBox = new JCheckBox();
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
CheckComboStore store = (CheckComboStore) value;
checkBox.setText(store.id);
checkBox.setSelected(((Boolean) store.state).booleanValue());
checkBox.setBackground(isSelected ? Color.red : Color.white);
checkBox.setForeground(isSelected ? Color.white : Color.black);
return checkBox;
}
}
class CheckComboStore {
String id;
Boolean state;
public CheckComboStore(String id, Boolean state) {
this.id = id;
this.state = state;
}
}
Related
I was changing the LookAndFeel of a JTable populated of Custom Class extended of JPanel , But I can't to do it.
I edited to simply my code, but still it's long.
public class LAF_TableCustomContainer extends JFrame {
public LAF_TableCustomContainer() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300, 300);
setVisible(true);
setLocationRelativeTo(null);
}
public static void changeLAF(Container container, String laf) {
try {
UIManager.setLookAndFeel(laf);
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
}
SwingUtilities.updateComponentTreeUI(container);
}
static final JFrame frame = new JFrame();
public JComponent makeUI() {
String[] hdrsObjects = {"PanelSpinnerRadioButton Class Column"};
Object[][] objectMatrix = new Object[3][1];
objectMatrix[0][0] = new PanelSpinnerRadioButtonData(false, 10, 40);
objectMatrix[1][0] = new PanelSpinnerRadioButtonData(true, 20, 40);
objectMatrix[2][0] = new PanelSpinnerRadioButtonData(false, 30, 40);
JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects));
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
table.setRowHeight(30);
TableColumn tc = table.getColumn("PanelSpinnerRadioButton Class Column");
tc.setCellRenderer(new PSRBTableCellRenderer());
tc.setCellEditor(new PSRBTableCellEditor());
JPanel pH = new JPanel();
pH.setLayout(new BoxLayout(pH, BoxLayout.LINE_AXIS));
JButton bMetal = new JButton("Metal");
bMetal.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
changeLAF(LAF_TableCustomContainer.this, "javax.swing.plaf.metal.MetalLookAndFeel");
changeLAF(table, "javax.swing.plaf.metal.MetalLookAndFeel");
changeLAF(scrollPane, "javax.swing.plaf.metal.MetalLookAndFeel");
changeLAF((JPanel)table.getModel().getValueAt(0, 0), "javax.swing.plaf.metal.MetalLookAndFeel");
}
});
JButton bMotif = new JButton("Motif");
bMotif.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
changeLAF(LAF_TableCustomContainer.this, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
changeLAF(table, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
changeLAF(scrollPane, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
changeLAF((JPanel)table.getModel().getValueAt(0, 0), "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
}
});
JButton bNimbus = new JButton("Nimbus");
bNimbus.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
changeLAF(LAF_TableCustomContainer.this, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
changeLAF(table, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
changeLAF(scrollPane, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
changeLAF((JPanel)table.getModel().getValueAt(0, 0), "javax.swing.plaf.nimbus.NimbusLookAndFeel");
}
});
pH.add(bMetal);
pH.add(bMotif);
pH.add(bNimbus);
JPanel pV = new JPanel();
pV.setLayout(new BoxLayout(pV, BoxLayout.PAGE_AXIS));
pV.add(pH);
pV.add(scrollPane);
return pV;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
LAF_TableCustomContainer f = new LAF_TableCustomContainer();
f.getContentPane().add(f.makeUI());
});
}
}
class PanelSpinnerRadioButtonData {
private boolean opt02 = false;
private Integer from = 0;
private Integer size = 1;
PanelSpinnerRadioButtonData() {
this(false, 5, 10);
}
PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
this.opt02 = opt02;
this.from = from;
this.size = size;
}
public boolean getOption() {
return opt02;
}
public Integer getFrom() {
return from;
}
public Integer getSize() {
return size;
}
}
class PanelSpinnerRadioButton extends JPanel {
public final JRadioButton jrbOption01 = new JRadioButton("01");
public final JRadioButton jrbOption02 = new JRadioButton("12");
public final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));
private final JPanel panel = new JPanel();
PanelSpinnerRadioButton() {
this(new PanelSpinnerRadioButtonData(false, 20, 40));
}
PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
super();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(jrbOption01);
panel.add(jrbOption02);
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(new JSeparator(JSeparator.VERTICAL));
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(jspnValues);
ButtonGroup bg = new ButtonGroup();
bg.add(jrbOption01);
bg.add(jrbOption02);
((SpinnerNumberModel) jspnValues.getModel()).setMaximum(data.getSize());
setData(data);
init();
}
private void init() {
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBackground(new Color(0, 0, 0, 0));
add(panel);
}
public void setData(PanelSpinnerRadioButtonData data) {
if (data.getOption()) {
jrbOption02.setSelected(true);
} else {
jrbOption01.setSelected(true);
}
((SpinnerNumberModel) jspnValues.getModel()).setValue(data.getFrom());
}
// Used in PSRBTableCellEditor.getCellEditorValue()
public PanelSpinnerRadioButtonData getData() {
return new PanelSpinnerRadioButtonData(
jrbOption02.isSelected(),
(Integer) ((SpinnerNumberModel) jspnValues.getModel()).getValue(),
(Integer) ((SpinnerNumberModel) jspnValues.getModel()).getMaximum());
}
}
class PSRBTableCellRenderer implements TableCellRenderer {
private final PanelSpinnerRadioButton renderer = new PanelSpinnerRadioButton();
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
renderer.setData((PanelSpinnerRadioButtonData) value);
}
return renderer;
}
}
class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private final PanelSpinnerRadioButton editor = new PanelSpinnerRadioButton();
#Override public Object getCellEditorValue() {
return editor.getData();
}
#Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
editor.setData((PanelSpinnerRadioButtonData) value);
}
return editor;
}
}
When I press some button all JFrame changes except the cells of JTable, containing my custom JPanel.
I tried forcing only the first cell...
changeLAF((JPanel)table.getModel().getValueAt(0, 0), "javax.swing.plaf.metal.MetalLookAndFeel");
But I got Exception:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: PanelSpinnerRadioButtonData cannot be cast to javax.swing.JPanel
The limitation of the SwingUtilities#updateComponentTreeUI(...) method is that the cell renderer LookAndFeel can not change
Since PSRBTableCellRenderer does not extends JComponent, it is not subject to LookAndFeel update in the SwingUtilities # updateComponentTreeUI (...) method
// #see javax/swing/SwingUtilities.java
public static void updateComponentTreeUI(Component c) {
updateComponentTreeUI0(c);
c.invalidate();
c.validate();
c.repaint();
}
private static void updateComponentTreeUI0(Component c) {
if (c instanceof JComponent) {
JComponent jc = (JComponent) c;
jc.updateUI();
JPopupMenu jpm =jc.getComponentPopupMenu();
if(jpm != null) {
updateComponentTreeUI(jpm);
}
}
Component[] children = null;
if (c instanceof JMenu) {
children = ((JMenu)c).getMenuComponents();
}
else if (c instanceof Container) {
children = ((Container)c).getComponents();
}
if (children != null) {
for (Component child : children) {
updateComponentTreeUI0(child);
}
}
}
You can avoid this by overriding the JTable#updateUI() method and recreating the cell renderer and editor.
JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects)) {
#Override public void updateUI() {
super.updateUI();
setRowHeight(30);
TableColumn tc = getColumn("PanelSpinnerRadioButton Class Column");
tc.setCellRenderer(new PSRBTableCellRenderer());
tc.setCellEditor(new PSRBTableCellEditor());
}
};
LAF_TableCustomContainer2.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class LAF_TableCustomContainer2 extends JFrame {
public LAF_TableCustomContainer2() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(300, 300);
setVisible(true);
setLocationRelativeTo(null);
}
public static void changeLAF(Container container, String laf) {
try {
UIManager.setLookAndFeel(laf);
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
}
SwingUtilities.updateComponentTreeUI(container);
}
static final JFrame frame = new JFrame();
public JComponent makeUI() {
JPanel pV = new JPanel();
pV.setLayout(new BoxLayout(pV, BoxLayout.PAGE_AXIS));
String[] hdrsObjects = {"PanelSpinnerRadioButton Class Column"};
Object[][] objectMatrix = new Object[3][1];
objectMatrix[0][0] = new PanelSpinnerRadioButtonData(false, 10, 40);
objectMatrix[1][0] = new PanelSpinnerRadioButtonData(true, 20, 40);
objectMatrix[2][0] = new PanelSpinnerRadioButtonData(false, 30, 40);
JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects)) {
#Override public void updateUI() {
super.updateUI();
setRowHeight(30);
TableColumn tc = getColumn("PanelSpinnerRadioButton Class Column");
tc.setCellRenderer(new PSRBTableCellRenderer());
tc.setCellEditor(new PSRBTableCellEditor());
}
};
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
// table.setRowHeight(30);
// TableColumn tc = table.getColumn("PanelSpinnerRadioButton Class Column");
// tc.setCellRenderer(new PSRBTableCellRenderer());
// tc.setCellEditor(new PSRBTableCellEditor());
JPanel pH = new JPanel();
pH.setLayout(new BoxLayout(pH, BoxLayout.LINE_AXIS));
JButton bMetal = new JButton("Metal");
bMetal.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
changeLAF(pV, "javax.swing.plaf.metal.MetalLookAndFeel");
}
});
JButton bMotif = new JButton("Motif");
bMotif.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
changeLAF(pV, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
}
});
JButton bNimbus = new JButton("Nimbus");
bNimbus.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
changeLAF(pV, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
}
});
pH.add(bMetal);
pH.add(bMotif);
pH.add(bNimbus);
pV.add(pH);
pV.add(scrollPane);
return pV;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
LAF_TableCustomContainer2 f = new LAF_TableCustomContainer2();
f.getContentPane().add(f.makeUI());
});
}
}
class PanelSpinnerRadioButtonData {
private boolean opt02 = false;
private Integer from = 0;
private Integer size = 1;
PanelSpinnerRadioButtonData() {
this(false, 5, 10);
}
PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
this.opt02 = opt02;
this.from = from;
this.size = size;
}
public boolean getOption() {
return opt02;
}
public Integer getFrom() {
return from;
}
public Integer getSize() {
return size;
}
}
class PanelSpinnerRadioButton extends JPanel {
public final JRadioButton jrbOption01 = new JRadioButton("01");
public final JRadioButton jrbOption02 = new JRadioButton("12");
public final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));
private final JPanel panel = new JPanel();
PanelSpinnerRadioButton() {
this(new PanelSpinnerRadioButtonData(false, 20, 40));
}
PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
super();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(jrbOption01);
panel.add(jrbOption02);
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(new JSeparator(JSeparator.VERTICAL));
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(jspnValues);
ButtonGroup bg = new ButtonGroup();
bg.add(jrbOption01);
bg.add(jrbOption02);
((SpinnerNumberModel) jspnValues.getModel()).setMaximum(data.getSize());
setData(data);
init();
}
private void init() {
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBackground(new Color(0, 0, 0, 0));
add(panel);
}
public void setData(PanelSpinnerRadioButtonData data) {
if (data.getOption()) {
jrbOption02.setSelected(true);
} else {
jrbOption01.setSelected(true);
}
((SpinnerNumberModel) jspnValues.getModel()).setValue(data.getFrom());
}
// Used in PSRBTableCellEditor.getCellEditorValue()
public PanelSpinnerRadioButtonData getData() {
return new PanelSpinnerRadioButtonData(
jrbOption02.isSelected(),
(Integer)((SpinnerNumberModel) jspnValues.getModel()).getValue(),
(Integer)((SpinnerNumberModel) jspnValues.getModel()).getMaximum());
}
}
class PSRBTableCellRenderer implements TableCellRenderer {
private final PanelSpinnerRadioButton renderer = new PanelSpinnerRadioButton();
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
renderer.setData((PanelSpinnerRadioButtonData) value);
}
return renderer;
}
}
class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private final PanelSpinnerRadioButton editor = new PanelSpinnerRadioButton();
#Override public Object getCellEditorValue() {
return editor.getData();
}
#Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
editor.setData((PanelSpinnerRadioButtonData) value);
}
return editor;
}
}
I would like to create a JTable in my application.
The table will contain two coumns, the first is the name of a software module.
The second column needs to contain a JComboBox with the revision numbers of the software module in the first column.
Is it even possible or I need to find another way to do this? (For example: put a button to the cell and choose the revision from a popup window)
Thank you in advance!
Here is one possible implementation to use a DefaultComboBoxModel<Integer> as the table column's data type:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class EditableComboCellEditorTest {
private JComponent makeUI() {
String[] columnNames = {"version", "revision"};
Object[][] data = {
{"1.7.0", makeModel(76, 79, 80)},
{"1.8.0", makeModel(91, 92, 101, 102)},
};
TableModel model = new DefaultTableModel(data, columnNames) {
#Override public Class<?> getColumnClass(int column) {
return column == 1 ? DefaultComboBoxModel.class : String.class;
}
};
JTable table = new JTable(model);
table.setRowHeight(32);
table.setAutoCreateRowSorter(true);
TableColumn col = table.getColumnModel().getColumn(1);
col.setCellRenderer(new ComboCellRenderer());
col.setCellEditor(new ComboCellEditor());
return new JScrollPane(table);
}
private static DefaultComboBoxModel<Integer> makeModel(Integer... items) {
return new DefaultComboBoxModel<Integer>(items) {
#Override public String toString() {
return Objects.toString(getSelectedItem(), "");
}
};
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new EditableComboCellEditorTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class ComboCellRenderer implements TableCellRenderer {
private final JPanel p = new JPanel(new GridBagLayout());
private final JComboBox<Integer> cb = new JComboBox<>();
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
p.removeAll();
p.setOpaque(false);
p.add(cb);
cb.setEditable(true);
cb.removeAllItems();
if (value instanceof DefaultComboBoxModel) {
DefaultComboBoxModel m = (DefaultComboBoxModel) value;
Object o = m.getSelectedItem();
if (o instanceof Integer) {
cb.addItem((Integer) o);
}
}
return p;
}
}
//https://java-swing-tips.blogspot.jp/2016/08/use-editable-jcombobox-as.html
class ComboCellEditor extends AbstractCellEditor implements TableCellEditor {
private final JPanel p = new JPanel(new GridBagLayout());
private final JComboBox<Integer> cb = new JComboBox<>();
protected ComboCellEditor() {
super();
cb.setEditable(true);
cb.addActionListener(e -> fireEditingStopped());
p.add(cb);
p.setOpaque(false);
}
#Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof ComboBoxModel) {
#SuppressWarnings("unchecked")
ComboBoxModel<Integer> m = (ComboBoxModel<Integer>) value;
cb.setModel(m);
}
return p;
}
#Override public Object getCellEditorValue() {
#SuppressWarnings("unchecked")
DefaultComboBoxModel<Integer> m = (DefaultComboBoxModel<Integer>) cb.getModel();
if (cb.isEditable()) {
Object o = cb.getEditor().getItem();
if (o instanceof Integer && m.getIndexOf((Integer) o) < 0) {
Integer value = (Integer) o;
int n = m.getSize();
Vector<Integer> list = new Vector<>(n + 1);
for (int i = 0; i < n; i++) {
list.add(m.getElementAt(i));
}
list.add(value);
Collections.sort(list);
m = new DefaultComboBoxModel<Integer>(list);
cb.setModel(m);
cb.setSelectedIndex(m.getIndexOf(value));
}
}
return m;
}
}
Override the getCellEditor(...) method to return the combo box:
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableComboBoxByRow extends JPanel
{
List<String[]> editorData = new ArrayList<String[]>(3);
public TableComboBoxByRow()
{
setLayout( new BorderLayout() );
// Create the editorData to be used for each row
editorData.add( new String[]{ "Red", "Blue", "Green" } );
editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
editorData.add( new String[]{ "Apple", "Orange", "Banana" } );
// Create the table with default data
Object[][] data =
{
{"Color", "Red"},
{"Shape", "Square"},
{"Fruit", "Banana"},
{"Plain", "Text"}
};
String[] columnNames = {"Type","Value"};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model)
{
// Determine editor to be used by row
public TableCellEditor getCellEditor(int row, int column)
{
int modelColumn = convertColumnIndexToModel( column );
if (modelColumn == 1 && row < 3)
{
JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
return new DefaultCellEditor( comboBox1 );
}
else
return super.getCellEditor(row, column);
}
};
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
// table.getColumnModel().getColumn(1).setCellRenderer(new ComboBoxRenderer2() );
}
/*
class ComboBoxRenderer2 extends DefaultTableCellRenderer
{
#Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setIcon(UIManager.getIcon("Table.descendingSortIcon"));
return label;
}
}
*/
private static void createAndShowUI()
{
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableComboBoxByRow() );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Hello all i have the following situation, I want to set all columns in a JTable to be a specific renderer (centered) and I want the right most column to have a background color as yellow. I've tried with the following code:
public class LView extends JInternalFrame {
private static final long serialVersionUID = -4248667075312220111L;
private LModel model;
private JPanel mainPanel;
private JButton btnRefresh;
private JTable lTable;
private DefaultTableModel lTableModel;
private String [] columnNames = {"col1", "col2", "col3", "col4", "col5"};
public LView() {
super("L Title", true, true, true, true);
setSize(650,300);
mainPanel = new JPanel(new FlowLayout());
JPanel topPanel = new JPanel();
btnRefresh = new JButton("Refresh");
btnRefresh.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
try { model.refresh(); }
catch (Exception e) { model.logException(e); }
}
});
topPanel.add(btnRefresh);
lTableModel = new DefaultTableModel() {
private static final long serialVersionUID = 2130745775009581358L;
#Override
public boolean isCellEditable(int row, int col) {
return false;
}
};
for (String col : columnNames)
lTableModel.addColumn(col);
lTable = new JTable();
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment( SwingConstants.CENTER );
lTable.setDefaultRenderer(Object.class, centerRenderer);
DefaultTableCellRenderer estColumnRenderer = new DefaultTableCellRenderer();
estColumnRenderer.setBackground(java.awt.Color.YELLOW);
estColumnRenderer.setFont(new Font(null, Font.BOLD, 12));
estColumnRenderer.setHorizontalAlignment( SwingConstants.CENTER );
lTable.setModel(lTableModel);
lTable.getColumnModel().getColumn(columnNames.length-1).setCellRenderer(estColumnRenderer);
lTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
lTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
lTable.getColumn(columnNames[0]).setPreferredWidth(225);
JScrollPane scrollPane = new JScrollPane(lTable);
JPanel tablePanel = new JPanel();
tablePanel.add(scrollPane);
mainPanel.add(topPanel);
mainPanel.add(tablePanel);
add(mainPanel);
}
public LModel getModel() {
return model;
}
public void setModel(LModel model) {
this.model = model;
}
public void addData(List<Object []> dataList) throws Exception {
lTableModel.getDataVector().removeAllElements();
lTableModel.fireTableDataChanged();
for (Object [] data : dataList) {
lmeTableModel.addRow(new Object[] {data[0],
data[1],
data[2],
data[3],
data[4]});
}
lTable.setPreferredScrollableViewportSize(lTable.getPreferredSize());
lTable.setFillsViewportHeight(true);
lTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
lTableModel.fireTableStructureChanged();
}
}
It sets all the columns to the top "centerRenderer" but the last column is not altered in any way. Am I missing something? Thanks -
EDIT: full code
I'm very new to programming, and I can't add JCheckbox to the JList. There is no error but nothing is displayed.
JFrame f=new JFrame();
String[] labels={"a","b","c","d","e"};
JCheckBox[] ch=new JCheckBox[labels.length];
JList list=new JList();
for (int i = 0; i < labels.length; i++) {
ch[i]=new JCheckBox("CheckBox"+i);
list.add(ch[i]);
}
JScrollPane pane=new JScrollPane(list);
f.add(pane);
f.setVisible(true);
As an alternative to the JTable solution that trashgod posted, you can also create the appearance of JCheckBoxes in a JList by:
Use a custom renderer for your JList that will show each item as a JCheckBox
Use a custom object in your JList that maintains it's boolean "checked" state
Add a MouseListener to the JList that will set/unset the checked state of each item.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class JCheckBoxListDemo implements Runnable
{
private JList jlist;
public static void main(String args[])
{
SwingUtilities.invokeLater(new JCheckBoxListDemo());
}
public void run()
{
Object[] items = new CheckListItem[] {
new CheckListItem("Apple"),
new CheckListItem("Banana"),
new CheckListItem("Carrot"),
new CheckListItem("Date"),
new CheckListItem("Eggplant"),
new CheckListItem("Fig"),
new CheckListItem("Guava"),
};
jlist = new JList(items);
jlist.setCellRenderer(new CheckBoxListRenderer());
jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jlist.setVisibleRowCount(5);
jlist.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent event)
{
selectItem(event.getPoint());
}
});
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0);
Object mapKey = keyStroke.toString();
jlist.getInputMap().put(keyStroke, mapKey);
jlist.getActionMap().put(mapKey, new AbstractAction()
{
public void actionPerformed(ActionEvent event)
{
toggleSelectedItem();
}
});
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(jlist));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void selectItem(Point point)
{
int index = jlist.locationToIndex(point);
if (index >= 0)
{
CheckListItem item = (CheckListItem)jlist.getModel().getElementAt(index);
item.setSelected(!item.isSelected());
jlist.repaint(jlist.getCellBounds(index, index));
}
}
private void toggleSelectedItem()
{
int index = jlist.getSelectedIndex();
if (index >= 0)
{
CheckListItem item = (CheckListItem)jlist.getModel().getElementAt(index);
item.setSelected(!item.isSelected());
jlist.repaint(jlist.getCellBounds(index, index));
}
}
private class CheckListItem
{
private Object item;
private boolean selected;
public CheckListItem(Object item)
{
this.item = item;
}
#SuppressWarnings("unused")
public Object getItem()
{
return item;
}
public boolean isSelected()
{
return selected;
}
public void setSelected(boolean isSelected)
{
this.selected = isSelected;
}
#Override
public String toString()
{
return item.toString();
}
}
private class CheckBoxListRenderer extends JCheckBox
implements ListCellRenderer
{
public Component getListCellRendererComponent(JList comp, Object value,
int index, boolean isSelected, boolean hasFocus)
{
setEnabled(comp.isEnabled());
setSelected(((CheckListItem) value).isSelected());
setFont(comp.getFont());
setText(value.toString());
if (isSelected)
{
setBackground(comp.getSelectionBackground());
setForeground(comp.getSelectionForeground());
}
else
{
setBackground(comp.getBackground());
setForeground(comp.getForeground());
}
return this;
}
}
}
A JList renderer can draw a checkbox, but JList does not support a cell editor. Instead, consider a one-column JTable. The default renderer & editor for a column of type Boolean.class is a JCheckBox, for example.
Here is what you might be looking for:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class CheckBo
{
public static void main(String[] args)
{
JFrame f=new JFrame();
String[]labels={"a","b","c","d","e"};
JCheckBox[]ch=new JCheckBox[labels.length];
final DefaultListModel model = new DefaultListModel();
JList list=new JList(model);
list.setCellRenderer(new CheckListRenderer());
for (int i = 0; i < labels.length; i++) {
//ch[i]=new JCheckBox("CheckBox"+i);
model.addElement(new CheckListItem("CheckBox"+i));
}
JScrollPane pane=new JScrollPane(list);
list.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent event)
{
JList list = (JList) event.getSource();
// Get index of item clicked
int index = list.locationToIndex(event.getPoint());
CheckListItem item = (CheckListItem)
list.getModel().getElementAt(index);
// Toggle selected state
item.setSelected(! item.isSelected());
// Repaint cell
list.repaint(list.getCellBounds(index, index));
}
});
f.add(pane);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
static class CheckListItem
{
private String label;
private boolean isSelected = false;
public CheckListItem(String label)
{
this.label = label;
}
public boolean isSelected()
{
return isSelected;
}
public void setSelected(boolean isSelected)
{
this.isSelected = isSelected;
}
public String toString()
{
return label;
}
}
static class CheckListRenderer extends JCheckBox implements ListCellRenderer
{
public Component getListCellRendererComponent(JList list, Object value, int index,boolean isSelected, boolean hasFocus)
{
setEnabled(list.isEnabled());
setSelected(((CheckListItem)value).isSelected());
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
setText(value.toString());
return this;
}
}
}
Source for above code is this
There are a lot of time, that I'm trying to make the Cell Renderer in the JavaOne 2007's talk maked by Shanon Hickey, Romain Guy and Chris Campbell, in the pages 38 and 39 (that you can find here : http://docs.huihoo.com/javaone/2007/desktop/TS-3548.pdf).
I asked Romain Guy, and Chris campbell, but without success, they say that they cannot pulish the source code.
So, any one can, give an idea, or even a source code on how to make this complex cell renderer ?
I learned this slides of many times, they say :
1)Cell Renderer: Column Spanning
Viewport clips column contents
and
2) Viewport moves to
expose the right text
for each column
I don't understand that, please can you give more in depth explanations ?
Cheers
Windows 7
JDK 1.7.0_21
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class ComplexCellRendererTest {
private static boolean DEBUG = true;
private JRadioButton r1 = new JRadioButton("scrollRectToVisible");
private JRadioButton r2 = new JRadioButton("setViewPosition");
public JComponent makeUI() {
String[] columnNames = {"AAA", "BBB"};
Object[][] data = {
{new Test("1", "aaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), "4"},
{new Test("2", "1234567890\nabcdefghijklmdopqrstuvwxyz"), "5"},
{new Test("3", "ccccccccccccccccccccccccccccccccccc\ndddddddddddd"), "6"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
#Override public boolean isCellEditable(int row, int column) {
return false;
}
};
final JTable table = new JTable(model);
table.getTableHeader().setReorderingAllowed(false);
table.setRowSelectionAllowed(true);
table.setFillsViewportHeight(true);
table.setShowVerticalLines(false);
table.setIntercellSpacing(new Dimension(0,1));
table.setRowHeight(56);
for(int i=0; i<table.getColumnModel().getColumnCount(); i++) {
TableColumn c = table.getColumnModel().getColumn(i);
c.setCellRenderer(new ComplexCellRenderer());
c.setMinWidth(50);
}
ActionListener al = new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
DEBUG = (e.getSource()==r1);
table.repaint();
}
};
Box box = Box.createHorizontalBox();
ButtonGroup bg = new ButtonGroup();
box.add(r1); bg.add(r1); r1.addActionListener(al);
box.add(r2); bg.add(r2); r2.addActionListener(al);
r1.setSelected(true);
JPanel p = new JPanel(new BorderLayout());
p.add(box, BorderLayout.NORTH);
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 f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ComplexCellRendererTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
static class ComplexCellRenderer extends JPanel implements TableCellRenderer {
private final JTextArea textArea = new JTextArea(2, 999999);
private final JLabel label = new JLabel();
private final JScrollPane scroll = new JScrollPane();
public ComplexCellRenderer() {
super(new BorderLayout(0,0));
scroll.setViewportView(textArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setViewportBorder(BorderFactory.createEmptyBorder());
scroll.setOpaque(false);
scroll.getViewport().setOpaque(false);
textArea.setBorder(BorderFactory.createEmptyBorder());
//textArea.setMargin(new Insets(0,0,0,0));
textArea.setForeground(Color.RED);
textArea.setOpaque(false);
label.setBorder(BorderFactory.createMatteBorder(0,0,1,1,Color.GRAY));
setBackground(Color.WHITE);
setOpaque(true);
add(label, BorderLayout.NORTH);
add(scroll);
}
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Test test;
if(value instanceof Test) {
test = (Test)value;
} else {
String title = value.toString();
Test t = (Test)table.getModel().getValueAt(row, 0);
test = new Test(title, t.text);
}
label.setText(test.title);
textArea.setText(test.text);
Rectangle cr = table.getCellRect(row, column, false);
if(DEBUG) {
//Unexplained flickering on first row?
textArea.scrollRectToVisible(cr);
} else {
//Work fine for me (JDK 1.7.0_21, Windows 7 64bit):
scroll.getViewport().setViewPosition(cr.getLocation());
}
if(isSelected) {
setBackground(Color.ORANGE);
} else {
setBackground(Color.WHITE);
}
return this;
}
}
}
class Test {
public final String title;
public final String text;
//public final Icon icon;
public Test(String title, String text) {
this.title = title;
this.text = text;
}
}