Change Background color of leaf of Tree - swing

Want to change color of only leaf of tree on one particular condition.
if (l_sel_node_object.getIsEnabled().trim().equalsIgnoreCase("N"))
defaultTreeCellRenderer.setBackgroundSelectionColor(Color.red);
but it is changing background of each selected node.Can anyone please help me out.

Only tested on Metal Look and Feel:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class MainPanel {
public JPanel makeUI() {
JTree tree = new JTree();
tree.setCellRenderer(new RedTreeCellRenderer());
JPanel p = new JPanel(new BorderLayout(5, 5));
p.add(new JScrollPane(tree));
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 MainPanel().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
//*
class RedTreeCellRenderer extends DefaultTreeCellRenderer {
#Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean isSelected,
boolean expanded, boolean leaf, int row, boolean hasFocus) {
JComponent c = (JComponent)super.getTreeCellRendererComponent(
tree, value, isSelected, expanded, leaf, row, hasFocus);
if(isSelected) {
c.setForeground(getTextSelectionColor());
if (leaf && value.toString().equalsIgnoreCase("red")) {
//<strong>
c.setOpaque(true);
//</strong>
c.setBackground(Color.RED);
} else {
c.setOpaque(false);
c.setBackground(getBackgroundSelectionColor());
}
} else {
c.setOpaque(false);
c.setForeground(getTextNonSelectionColor());
c.setBackground(getBackgroundNonSelectionColor());
}
return c;
}
}
/*/
class RedTreeCellRenderer2 extends DefaultTreeCellRenderer {
#Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean isSelected,
boolean expanded, boolean leaf, int row, boolean hasFocus) {
JComponent c = (JComponent)super.getTreeCellRendererComponent(
tree, value, isSelected, expanded, leaf, row, hasFocus);
if(isSelected) {
if(leaf) {
setParticularCondition(value.toString());
}
c.setForeground(getTextSelectionColor());
c.setBackground(getBackgroundSelectionColor());
} else {
c.setForeground(getTextNonSelectionColor());
c.setBackground(getBackgroundNonSelectionColor());
}
return c;
}
boolean particularCondition = false;
private void setParticularCondition(String str) {
particularCondition = str.equalsIgnoreCase("red");
}
#Override public Color getBackgroundSelectionColor() {
if(particularCondition) return Color.RED;
else return super.getBackgroundSelectionColor();
}
}
//*/

Related

Java JTable - Combobox + Checkbox - Cellrenderer + Editor

i got a Problem.
I have a JTable, containing descriptors in the first column, and then different types of
JComponents in the second column (JTextField as standard, JCheckBox for Boolean and JCombobox for Integers)
I created my own Cellrenderer, to do so, but when i try to change the value of (to edit) f.e. the JCheckBox, the CheckBox dissapears, and there is a normal TextField.
So I tried to write my own CellEditor, but it doesnt really work.
Might you guys help me please?
Thanks
Developer_X
String[] columnNames =
{"", ""};
Object[][] data =
{
{ "A", ""},
{ "B", ""},
{ "C", new Integer(0) },
{ "D", new Boolean(true) },
{ "E", "A.B.C" },
{ "F", "Rhababer" }
};
JTable table = new JTable(data, columnNames)
{
private static final long serialVersionUID = 1L;
#Override
public boolean isCellEditable(int row, int column)
{
if(column==0)
return false;
else
return true;
}
};
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(false);
table.setCellSelectionEnabled(false);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setDefaultRenderer( Object.class, new FormalDataCellRenderer(table.getDefaultRenderer(Object.class)));
table.setDefaultRenderer( Boolean.class, new FormalDataCellRenderer(table.getDefaultRenderer(Boolean.class)));
table.setDefaultRenderer( Integer.class, new FormalDataCellRenderer(table.getDefaultRenderer(Integer.class)));
table.setDefaultEditor(Object.class, new FormalDataCellEditor(table.getCellEditor()));
// FormalDataCellRenderer
public class FormalDataCellRenderer implements TableCellRenderer
{
private TableCellRenderer normal;
public FormalDataCellRenderer(TableCellRenderer cellRenderer)
{
super();
this.normal = cellRenderer;
}
public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row,int column)
{
if(column==1)
{
if(value instanceof Boolean)
{
return new JCheckBox("",value.equals(new Boolean(true)));
}
else if(value instanceof Integer)
{
JComboBox<String> typeSelection = new JComboBox<String>();
typeSelection.addItem(sm.getString(StringConstants.PROFILE_GENDER_MALE));
typeSelection.addItem(sm.getString(StringConstants.PROFILE_GENDER_FEMALE));
typeSelection.setSelectedIndex((Integer)(value));
return typeSelection;
}
}
return normal.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
// FormalDataCellEditor
public class FormalDataCellEditor extends DefaultCellEditor
{
public FormalDataCellEditor(TableCellEditor editor)
{
super(new JCheckBox()); //? What shall I do?
}
#Override
public Component getTableCellEditorComponent(JTable table,Object value, boolean isSelected, int row, int column)
{
if(column==1)
{
System.out.println(value.toString());
if(value instanceof Boolean)
{
if(value.equals(new Boolean(true)))
{
value = new Boolean(false);
}
else
{
value = new Boolean(true);
}
return new JCheckBox("",value.equals(new Boolean(true)));
}
else if(value instanceof Integer)
{
JComboBox<String> typeSelection = new JComboBox<String>();
typeSelection.addItem(sm.getString(StringConstants.PROFILE_GENDER_MALE));
typeSelection.addItem(sm.getString(StringConstants.PROFILE_GENDER_FEMALE));
int selected = (Integer)(value);
if(selected<typeSelection.getItemCount()-1)
selected++;
else
selected = 0;
typeSelection.setSelectedIndex(selected);
value = new Integer(selected);
return typeSelection;
}
}
return super.getTableCellEditorComponent(table, value, isSelected,row, column);
}
}
So this is my complete example.
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.util.LinkedList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class EasyExample
{
// Attributes
// Constructor
public EasyExample()
{
}
// Methods
public static void main(String[] args)
{
Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
JFrame frame = new JFrame();
frame.setTitle("Table Example");
frame.setSize(screen.width/4, screen.height/2);
frame.setLocationRelativeTo(null);
frame.setLayout(new BorderLayout());
JPanel Panel = new JPanel();
Panel.setLayout(new BoxLayout(Panel,BoxLayout.Y_AXIS));
frame.add(Panel,"Center");
JPanel formalData = new JPanel();
formalData.setBorder(BorderFactory.createTitledBorder("Formal Data"));
formalData.setLayout(new BorderLayout());
Panel.add(formalData);
String[] columnNames = {"", ""};
Object[][] data =
{
{ "A", ""},
{ "B", ""},
{ "C", new Integer(0)},
{ "D", new Boolean(true)},
{ "E", "A.B.C" },
{ "F", "Rhababer"}
};
JTable table = new JTable(data, columnNames)
{
private static final long serialVersionUID = 1L;
public boolean isCellEditable(int row, int column)
{
if(column==0)
return false;
else
return true;
}
};
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(false);
table.setCellSelectionEnabled(false);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setDefaultRenderer( Object.class, new FormalDataCellRenderer(table.getDefaultRenderer(Object.class)));
table.setDefaultRenderer( Boolean.class, new FormalDataCellRenderer(table.getDefaultRenderer(Boolean.class)));
table.setDefaultRenderer( Integer.class, new FormalDataCellRenderer(table.getDefaultRenderer(Integer.class)));
table.setDefaultEditor(Object.class, new FormalDataCellEditor(table.getCellEditor()));
formalData.add(new JScrollPane(table));
frame.setVisible(true);
}
static class FormalDataCellRenderer implements TableCellRenderer
{
private TableCellRenderer normal;
public FormalDataCellRenderer(TableCellRenderer cellRenderer)
{
super();
this.normal = cellRenderer;
}
public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row,int column)
{
if(column==1)
{
if(value instanceof Boolean)
{
return new JCheckBox("",value.equals(new Boolean(true)));
}
else if(value instanceof Integer)
{
JComboBox<String> typeSelection = new JComboBox<String>();
typeSelection.addItem("male");
typeSelection.addItem("female");
typeSelection.setSelectedIndex((Integer)(value));
return typeSelection;
}
}
return normal.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
static class FormalDataCellEditor extends DefaultCellEditor
{
public FormalDataCellEditor(TableCellEditor editor)
{
super(new JCheckBox()); //? What shall I do?
}
#Override
public Component getTableCellEditorComponent(JTable table,Object value, boolean isSelected, int row, int column)
{
if(column==1)
{
if(value instanceof Boolean)
{
if(value.equals(new Boolean(true)))
{
value = new Boolean(false);
}
else
{
value = new Boolean(true);
}
return new JCheckBox("",value.equals(new Boolean(true)));
}
else if(value instanceof Integer)
{
JComboBox<String> typeSelection = new JComboBox<String>();
typeSelection.addItem("male");
typeSelection.addItem("female");
int selected = (Integer)(value);
if(selected<typeSelection.getItemCount()-1)
selected++;
else
selected = 0;
typeSelection.setSelectedIndex(selected);
value = new Integer(selected);
return typeSelection;
}
}
return super.getTableCellEditorComponent(table, value, isSelected,row, column);
}
}
}

How to disable JButton in the particular row in the JTable

I'm struggling with a at the first sight simple problem (and probably it is so...) - I have to disable certain button in the JTable upon value in one of the cells within the same row.
Below is my inner class for button rendering and editing:
private class CellButton {
class ButtonsPanel extends JPanel {
public JButton jbutton = new JButton("Accept!!");
public ButtonsPanel() {
super();
setOpaque(true);
jbutton.setFocusable(false);
jbutton.setRolloverEnabled(false);
jbutton.setSize(122, 30);
jbutton.setFont(new java.awt.Font("Tahoma", 3, 12));
jbutton.setForeground(new java.awt.Color(0, 102, 102));
add(jbutton);
}
private class ButtonsRenderer extends ButtonsPanel implements TableCellRenderer {
ButtonsPanel bp;
public ButtonsRenderer() {
super();
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
this.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
Object o = table.getModel().getValueAt(row, 8);
bp = (ButtonsPanel) o;
if (jTable5.getValueAt(row, 3).equals("NORMALNA")) {
bp.jbutton.setEnabled(false);
}
return this;
}
}
private class ButtonsEditor extends ButtonsPanel implements TableCellEditor {
ButtonsPanel bp;
public ButtonsEditor(final JTable table, final String tableName) {
super();
//DEBUG: view button click -> control key down + edit button(same cell) press -> remain selection color
MouseListener ml = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
ButtonModel m = ((JButton) e.getSource()).getModel();
if (m.isPressed() && table.isRowSelected(table.getEditingRow()) && e.isControlDown()) {
setBackground(table.getBackground());
}
}
};
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int row = table.convertRowIndexToModel(table.getEditingRow());
Object o = table.getModel().getValueAt(row, 0);
fireEditingStopped();
//update info status
setDmlUpdateStatusPrejeteInfo();
jDialog2.requestFocus();
}
});
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
fireEditingStopped();
}
});
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.setBackground(table.getSelectionBackground());
Object o = table.getModel().getValueAt(row, 8);
bp = (ButtonsPanel) o;
if (jTable5.getValueAt(row, 3).equals("NORMALNA")) {
bp.jbutton.setEnabled(false);
}
return this;
}
#Override
public Object getCellEditorValue() {
return "";
}
transient protected ChangeEvent changeEvent = null;
#Override
public boolean isCellEditable(EventObject e) {
return true;
}
#Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
#Override
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
#Override
public void cancelCellEditing() {
fireEditingCanceled();
}
#Override
public void addCellEditorListener(CellEditorListener l) {
listenerList.add(CellEditorListener.class, l);
}
#Override
public void removeCellEditorListener(CellEditorListener l) {
listenerList.remove(CellEditorListener.class, l);
}
public CellEditorListener[] getCellEditorListeners() {
return listenerList.getListeners(CellEditorListener.class);
}
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((CellEditorListener) listeners[i + 1]).editingStopped(changeEvent);
}
}
}
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((CellEditorListener) listeners[i + 1]).editingCanceled(changeEvent);
}
}
}
}
public ButtonsRenderer br() {
return new ButtonsRenderer();
}
public ButtonsEditor be(JTable jTable, String tableName) {
return new ButtonsEditor(jTable, tableName);
}
}
a) it's better not to call a Jbutton in the name Jbutton, it's just confusing
b) there are many way to disable a jbutton (make it disappear, remove it, resize it...) but the best one is probably this:
Jbutton.setEnabled(false);
c) I think you can use this very useful guide: http://www.macs.hw.ac.uk/guidebook/?name=JButton&page=1

JComboBox inside Jtable with GlazedLists AutocompleteSupport - getSelectedItem returns null

I'm using GlazedLists' AutoCompleteSupport to wrap a JComboBox used as cell editor for a JTable and am facing a problem to get selectedItem when I type a value in the editor that is not in the model.
The problem appears inside the stopCellEditing method, after you type something in the ComboBox that is not in the list. Even if something was typed in the editor, when invoking getItem() from stopCellEditing, null will be returned. Please see like 65 from the code below.
I would like to get the item from the editor to be able to add it to the ComboBox model.
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.swing.AutoCompleteSupport;
import java.awt.Component;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.HashMap;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class TestComboBoxGlazedLists {
public static void main(String[] args) {
TestComboBoxGlazedLists test = new TestComboBoxGlazedLists();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create and add a tabbed pane to the frame
JTabbedPane tabbedPane = new JTabbedPane();
frame.getContentPane().add(tabbedPane);
//create a table and add it to a scroll pane in a new tab
JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
JScrollPane scrollPane = new JScrollPane(table);
tabbedPane.addTab("test", scrollPane);
// create a simple JComboBox and set is as table cell editor on column A
TestComboBoxGlazedLists.UserRepository rep = new TestComboBoxGlazedLists.UserRepository();
TestComboBoxGlazedLists.UserInfo[] comboElements = rep.getAllUsers();
DefaultComboBoxModel model = new DefaultComboBoxModel(comboElements);
JComboBox comboBox = new JComboBox(model);
// GlazedLists
DefaultCellEditor cellEditor = new DefaultCellEditor(comboBox) {
private Object originalValue;
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
originalValue = value;
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
#Override
public boolean stopCellEditing() {
JComboBox comboBox = (JComboBox) getComponent();
ComboBoxModel comboModel = comboBox.getModel();
// this value is null when the selected item is not from the list
Object editingValue = getCellEditorValue();
// Needed because your TableModel is empty
if (editingValue == null) {
return super.stopCellEditing();
}
int selectedIndex = -1;
int modelSize = comboModel.getSize();
for (int i = 0; i < modelSize; i++) {
if (editingValue.equals(comboModel.getElementAt(i))) {
selectedIndex = i;
}
}
// Selecting item from model
if (!(selectedIndex == -1)) {
return super.stopCellEditing();
}
if (!(editingValue instanceof TestComboBoxGlazedLists.UserInfo)) {
// Confirm addition of new value
int result = JOptionPane.showConfirmDialog(
comboBox.getParent(),
"Add (" + editingValue + ") to table?",
"Update Model",
JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
TestComboBoxGlazedLists.UserInfo newUser = new TestComboBoxGlazedLists.UserInfo(editingValue.toString(), null);
comboBox.addItem(newUser);
comboBox.setSelectedItem(newUser);
return super.stopCellEditing();
}
}
return false;
}
};
// needs to be invoked from Event Dispatch Thread
SwingUtilities.invokeLater(new TestComboBoxGlazedLists.AutocompleteComboRunnable(table, comboBox));
// end GlazedLists
table.getColumn("A").setCellEditor(cellEditor);
table.getColumn("A").setCellRenderer(new TestComboBoxGlazedLists.CustomTableCellRenderer());
// pack and show frame
frame.pack();
frame.setVisible(true);
}
public class AutocompleteComboRunnable implements Runnable {
private JTable mTable;
private JComboBox mComboBox;
public AutocompleteComboRunnable(JTable table, JComboBox comboBox) {
mTable = table;
mComboBox = comboBox;
}
#Override
public void run() {
TextFilterator textFilterator = GlazedLists.textFilterator("firstName");
// ComboBoxCellEditor cellEditor = new ComboBoxCellEditor(comboBox);
TestComboBoxGlazedLists.UserRepository rep = new TestComboBoxGlazedLists.UserRepository();
AutoCompleteSupport support = AutoCompleteSupport.install(mComboBox,
GlazedLists.eventListOf(rep.getAllUsers()),
textFilterator,
new TestComboBoxGlazedLists.UserInfoFormat());
support.setStrict(false);
}
}
public class CustomTableCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value != null) {
// this is used to extract the data you want to display in the table from your "custom model"
TestComboBoxGlazedLists.UserInfo user = (TestComboBoxGlazedLists.UserInfo) value;
return super.getTableCellRendererComponent(table, user.getFirstName(), isSelected, hasFocus, row, column);
} else {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
}
public class UserInfo {
private String firstName;
private String lastName;
public UserInfo(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
public class UserRepository {
TestComboBoxGlazedLists.UserInfo[] comboElements;
HashMap<String, TestComboBoxGlazedLists.UserInfo> objectsMap;
public UserRepository() {
comboElements = new TestComboBoxGlazedLists.UserInfo[5];
comboElements[0] = new TestComboBoxGlazedLists.UserInfo("John", "Doe");
comboElements[1] = new TestComboBoxGlazedLists.UserInfo("Betty", "Doe");
comboElements[2] = new TestComboBoxGlazedLists.UserInfo("Elenor", "Smith");
comboElements[3] = new TestComboBoxGlazedLists.UserInfo("Helen", "Kelly");
comboElements[4] = new TestComboBoxGlazedLists.UserInfo("Joe", "Black");
objectsMap = new HashMap<>();
for (int i = 0; i < 5; i++) {
objectsMap.put(comboElements[i].getFirstName(), comboElements[i]);
}
}
public TestComboBoxGlazedLists.UserInfo getUserInfo(String name) {
return objectsMap.get(name);
}
public TestComboBoxGlazedLists.UserInfo[] getAllUsers() {
return comboElements;
}
}
private class UserInfoFormat extends Format {
#Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
if (obj != null) {
toAppendTo.append(((TestComboBoxGlazedLists.UserInfo) obj).getFirstName());
}
return toAppendTo;
}
#Override
public Object parseObject(String source, ParsePosition pos) {
TestComboBoxGlazedLists.UserRepository rep = new TestComboBoxGlazedLists.UserRepository();
return rep.getUserInfo(source.substring(pos.getIndex()));
}
}
}

I'm making a game in Java and whenever I try to bring up my in game menu the program minimizes?

The menu is displayed on game startup and works fine, but once in game you can hit escape to bring up the menu again and this will cause the program to minimize. After I unminimize the game I can hit escape again and the menu screen will appear as intended. The return button also works as intended. What is going on here?
EDIT
Here is my SSCCE:
You will just need to add the imports and unimplemented methods for BullsEyePanel. I hope this helps!
public class Board {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int B_WIDTH = (int) dim.getWidth();
int B_HEIGHT = (int) dim.getHeight();
JFrame f = new JFrame("Children of The Ape");
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.pack();
f.setBackground(Color.BLACK);
f.setVisible(true);
f.setResizable(false);
// Get graphics configuration...
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
// Change to full screen
gd.setFullScreenWindow(f);
if (gd.isDisplayChangeSupported()) {
gd.setDisplayMode(new DisplayMode(B_WIDTH, B_HEIGHT, 32, DisplayMode.REFRESH_RATE_UNKNOWN));
}
MenuPanel menu = new MenuPanel(f);
f.getContentPane().add(menu);
f.validate();
}
}
class BullsEyePanel extends JPanel implements MouseInputListener, ActionListener {
JFrame frame;
public BullsEyePanel(JFrame f) {
frame = f;
addKeyListener(new TAdapter());
setFocusable(true);
setVisible(true);
repaint();
}
private void openMenu() {
frame.getContentPane().add(new MenuPanel(this));
setVisible(false);
}
private class TAdapter extends KeyAdapter {
public void keyPressed(KeyEvent arg0) {
if (arg0.getKeyCode() == 27) {
openMenu();
}
}
}
}
class MenuPanel extends JPanel {
JButton btnExit;
JButton btnNewGame;
JFrame f;
BullsEyePanel panel;
MenuPanel(JFrame frame) { //this menu constructor is only called on program startup
f = frame;
setBackground(Color.black);
setFocusable(true);
btnNewGame = new JButton("New Game");
btnExit = new JButton("Exit");
btnNewGame.addActionListener(new newGameListener());
btnExit.addActionListener(new exitListener());
add(btnNewGame);
add(btnExit);
setVisible(true);
}
MenuPanel(BullsEyePanel bullsEyePanel) { //this menu constructor is called when ESC is typed
f = bullsEyePanel.frame;
setBackground(Color.black);
setFocusable(true);
btnNewGame = new JButton("New Game");
btnExit = new JButton("Exit");
btnNewGame.addActionListener(new newGameListener());
btnExit.addActionListener(new exitListener());
add(btnNewGame);
add(btnExit);
setVisible(true);
}
public class exitListener implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
}
public class newGameListener implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
f.getContentPane().add(new BullsEyePanel(f), BorderLayout.CENTER);
}
}
}
Instead of variant constructors, let the menu panel undertake its removal and restoration, as suggested below. See also this related example.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Board {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Board().createAndShowGUI();
}
});
}
public void createAndShowGUI() {
JFrame f = new JFrame("Children of The Board");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBackground(Color.BLACK);
MenuPanel menu = new MenuPanel(f);
f.add(menu, BorderLayout.NORTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class MenuPanel extends JPanel {
private JButton btnExit = new JButton("Exit");
private JButton btnNewGame = new JButton("New Game");
private BullsEyePanel gamePanel;
private JFrame parent;
MenuPanel(JFrame parent) {
this.gamePanel = new BullsEyePanel(this);
this.parent = parent;
this.setBackground(Color.black);
this.setFocusable(true);
btnNewGame.addActionListener(new newGameListener());
btnExit.addActionListener(new exitListener());
this.add(btnNewGame);
this.add(btnExit);
this.setVisible(true);
}
public void restore() {
parent.remove(gamePanel);
parent.add(this, BorderLayout.NORTH);
parent.pack();
parent.setLocationRelativeTo(null);
}
private class exitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
}
private class newGameListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
parent.remove(MenuPanel.this);
parent.add(gamePanel, BorderLayout.CENTER);
parent.pack();
parent.setLocationRelativeTo(null);
gamePanel.requestFocus();
}
}
}
class BullsEyePanel extends JPanel {
private MenuPanel menuPanel;
public BullsEyePanel(MenuPanel menu) {
this.menuPanel = menu;
this.setFocusable(true);
this.addKeyListener(new TAdapter());
this.setPreferredSize(new Dimension(320, 240)); // placeholder
this.setVisible(true);
}
private class TAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent code) {
if (code.getKeyCode() == KeyEvent.VK_ESCAPE) {
menuPanel.restore();
}
}
}
}

Swing: table cell rendering doesn't work right for JXTable?

I'm trying to override the highlight color of a JXTable based on the value of certain row items. Here's an example where the highlight is green if the row item value has getNumber() % 2 == 0.
It works fine for JTable, but for JXTable, it looks like the table cell renderer doesn't work unless the rows in question are selected. Why does it behave this way, and how do I fix it?
import java.awt.Color;
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.jdesktop.swingx.JXTable;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.gui.TableFormat;
import ca.odell.glazedlists.swing.EventTableModel;
public class TableRendererExample {
static public enum ItemKey {
NAME("name") {
#Override public String getStringFromItem(Item item) {
return item.getName();
}
},
NUMBER("#") {
#Override public String getStringFromItem(Item item) {
return Integer.toString(item.getNumber());
}
},
PARENT("parent") {
#Override public String getStringFromItem(Item item) {
Item p = item.getParent();
return (p == null) ? null : p.getName();
}
};
final private String name;
ItemKey(String name) { this.name = name; }
public String getName() { return this.name; }
abstract public String getStringFromItem(Item item);
static private ItemKey[] columns = { NAME, NUMBER, PARENT };
static public ItemKey[] getColumns() { return columns; }
}
static public class ItemTableFormat implements TableFormat<Item> {
#Override public int getColumnCount() {
return ItemKey.getColumns().length;
}
#Override public String getColumnName(int col) {
return ItemKey.getColumns()[col].getName();
}
#Override public Object getColumnValue(Item item, int col) {
return ItemKey.getColumns()[col].getStringFromItem(item);
}
}
static class Item {
final private String name;
final private int number;
final private Item parent;
private Item(String name, int number, Item parent) {
this.name=name; this.number=number; this.parent=parent;
}
static public Item create(String name, int number, Item parent) {
return new Item(name, number, parent);
}
public String getName() { return this.name; }
public int getNumber() { return this.number; }
public Item getParent() { return this.parent; }
}
static public void main(String[] args)
{
EventList<Item> items = new BasicEventList<Item>();
Item x1,x2,x3,x4;
x1 = Item.create("foo", 1, null);
items.add(x1);
x2 = Item.create("bar", 2, x1);
items.add(x2);
x3 = Item.create("baz", 1, x1);
items.add(x3);
x4 = Item.create("quux", 4, x2);
items.add(x4);
items.add(Item.create("wham", 3, x3));
items.add(Item.create("blam", 11, x3));
items.add(Item.create("shazaam", 20, x3));
items.add(Item.create("August", 8, x4));
items.add(Item.create("September", 9, x4));
items.add(Item.create("October", 10, x4));
items.add(Item.create("November", 11, x4));
items.add(Item.create("December", 12, x4));
EventList<Item> sortedItems = new SortedList<Item>(items, null);
final EventList<Item> displayList = sortedItems;
doit(new JTable(), "JTable cell renderer", displayList);
doit(new JXTable(), "JXTable cell renderer", displayList);
}
static public void doit(JTable table, String title,
final EventList<Item> displayList)
{
TableFormat<Item> tf = new ItemTableFormat();
EventTableModel<Item> etm =
new EventTableModel<Item>(displayList, tf);
table.setModel(etm);
if (table instanceof JXTable)
{
((JXTable)table).setColumnControlVisible(true);
}
TableColumnModel tcm = table.getColumnModel();
final Color selectedGreen = new Color(128, 255, 128);
final Color unselectedGreen = new Color(224, 255, 224);
TableCellRenderer tcr = new DefaultTableCellRenderer() {
#Override public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column)
{
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
Item item = displayList.get(row);
Color color = null;
if (item != null && ((item.getNumber() % 2) == 0))
{
color = isSelected ? selectedGreen : unselectedGreen;
}
if (color == null)
{
color = isSelected
? table.getSelectionBackground()
: table.getBackground();
}
c.setBackground(color);
return c;
}
};
for (int i = 0; i < tcm.getColumnCount(); ++i)
{
tcm.getColumn(i).setCellRenderer(tcr);
}
JPanel panel = new JPanel();
panel.add(new JScrollPane(table));
JFrame frame = new JFrame(title);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
}
}
I got a response from one of the SwingX folks who said that I needed to use a Highlighter (rather than a TableCellRenderer) for the renderers to behave properly.
There was a hacky workaround but he didn't recommend it.