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;
}
}
Related
I am working on a school project using BlueJay and I have created two classes in package Logic which are the Game class, and the VectorGames class.
In my package GUI, I created a class called AddGame and ViewGame class.
The issue that I have encountered is that, when I click the Save Button on Addgame, it saves the file only once. When I try to save it doesn't do or say anything it just stays there returning nothing. Another issue encountered is that on ViewGame, the gameType column is remaining empty ( this is from combo type box )
AddGame code :
package GUI;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import Logic.*;
public class AddGame extends JFrame implements ActionListener{
private JPanel north, south, east, west, center;
private JLabel titleLabel, westLabel, eastLabel;
private JTextField gameNameFld, gameKeyFld;
private JComboBox gameTypeCombo;
private JButton saveButton, clearButton;
private VectorGames vg;
public AddGame(){
super("Adding a Game");
this.setLayout(new BorderLayout());
vg = new VectorGames();
vg.readFromFile();
//north panel
north = new JPanel();
this.add(north,BorderLayout.NORTH);
titleLabel = new JLabel("Add a game below");
titleLabel.setFont(new Font("Verdana",Font.BOLD,20));
titleLabel.setForeground(Color.black);
north.add(titleLabel);
//west and east panels
west = new JPanel();
east = new JPanel();
this.add(west, BorderLayout.WEST);
this.add(east, BorderLayout.EAST);
westLabel = new JLabel(" ");
eastLabel = new JLabel(" ");
west.add(westLabel);
east.add(eastLabel);
//center panel
center = new JPanel();
this.add(center, BorderLayout.CENTER);
center.setLayout(new GridLayout(4,2,0,20));
gameNameFld = new JTextField();
gameKeyFld = new JTextField();
gameTypeCombo = new JComboBox();
gameTypeCombo.setModel(new DefaultComboBoxModel(new String[]
{"<--Select-->", "Arcade", "Puzzle", "Adventure", "Shooter", "Roleplay"}));
center.add(createLabel("Game Name"));
center.add(gameNameFld);
center.add(createLabel("Game Key"));
center.add(gameKeyFld);
center.add(createLabel("Game Type"));
center.add(gameTypeCombo);
//south panel
south = new JPanel();
south.setLayout(new FlowLayout());
this.add(south, BorderLayout.SOUTH);
clearButton = new JButton("Clear");
south.add(clearButton);
clearButton.addActionListener(this);
saveButton = new JButton("Save");
south.add(saveButton);
saveButton.addActionListener(this);
this.setSize(300,400);
this.setLocation(50,50);
this.setVisible(true);
}
private JLabel createLabel(String title){
return new JLabel(title);
}
private void clearFields(){
gameNameFld.setText("");
gameKeyFld.setText("");
gameTypeCombo.setSelectedIndex(0);
}
private boolean validateForm(){
boolean flag = false;
if(gameNameFld.getText().equals("")||gameKeyFld.getText().equals("")||
gameTypeCombo.getSelectedIndex()==0){
flag = true;
}
return flag;
}
public void actionPerformed(ActionEvent event){
if (event.getSource() == clearButton){
clearFields();
}
if(event.getSource() == saveButton){
if(validateForm() == true){
JOptionPane.showMessageDialog(null,"You have empty fields",
"Empty Fields", JOptionPane.ERROR_MESSAGE);
} else if(vg.checkGamebyGameKey(gameKeyFld.getText()) == true){
JOptionPane.showMessageDialog(null,"Game Key already exists!",
"Game Key Check", JOptionPane.ERROR_MESSAGE);
} else {
Game tempGame = new Game(gameNameFld.getText(),gameKeyFld.getText(),
(String)gameTypeCombo.getSelectedItem());
vg.addGame(tempGame);
vg.saveToFile();
JOptionPane.showMessageDialog(null, "Game added successfully!", "Adding a Game",
JOptionPane.INFORMATION_MESSAGE);
clearFields();
}
}
}
}
ViewGame code:
package GUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import Logic.*;
public class ViewGame extends JFrame {
private JTable table;
private VectorGames vg;
public ViewGame(){
super("Viewing Games by Name");
this.setLayout(new BorderLayout());
vg = new VectorGames();
vg.readFromFile();
vg.sortGamesByName();
int numOfGames = vg.getVectorSize();
int count = 0;
Game tempGame = new Game();
String[] tableHeader = {"Game Name", "Game Type", "Game Key"};
Object [][] tableContent = new Object[numOfGames][3];
for(int i = 0; i < numOfGames; i++){
tempGame = vg.getGamesByIndex(count);
tableContent[i][0] = tempGame.getGameName();
tableContent[i][2] = tempGame.getGameType();
tableContent[i][1] = tempGame.getGameKey();
}
table = new JTable (tableContent, tableHeader);
JScrollPane scrollPane = new JScrollPane(table);
table.setPreferredScrollableViewportSize(new Dimension(500, 400));
this.add(table.getTableHeader(), BorderLayout.NORTH);
this.add(table, BorderLayout.CENTER);
this.setSize(500,600);
this.setLocation(100,50);
this.setVisible(true);
}
}
Game code:
package Logic;
import java.io.*;
public class Game implements Serializable{ // Using serializable to allow easy save and read access
//Initializing variables related to Game
private String gameName, gameKey, gameType;
//Creating a constructor with the parameters for class Games
public Game(String gameName, String gamekey, String gameType){
setGameName(gameName);
setGameKey(gameKey);
setGameType(gameType);
}
//Setting up a parameterless constructor for class Games
public Game(){
}
public String getGameName(){//Get Method for gameName
return gameName;
}
public String getGameKey(){//Get Method for gameKey
return gameKey;
}
public String getGameType(){//Get Method for gameType
return gameType;
}
public void setGameName(String gameName){//Set Method for gameName
this.gameName = gameName;
}
public void setGameKey(String gameKey){//Set Method for gameKey
this.gameKey = gameKey;
}
public void setGameType(String gameType){//Set Method for gameType
this.gameType = gameType;
}
public String toString(){
return "Game Name : " + gameName + "\nGame Key : "
+ gameKey + "\nGame Type ; " + gameType;
}
}
VectorGames code:
package Logic;
import java.util.*;
import java.io.*;
import java.lang.*;
public class VectorGames extends IOException{
/* Add a Game, Remove a Game, getVectorGame Size, print allGamesAvailable,
* saveToFile , searchGame and return boolean literal, searchGame and return
* client object, sort games, readFromFile.
*
*/
private Vector<Game> games;
public VectorGames(){
games = new Vector<Game>();
}
//Adding a Game
public void addGame(Game game){
games.add(game);
}
public void deleteGame(Game game){
games.remove(game);
}
public int getVectorSize(){
return games.size();
}
public void clearVector(){
games.clear();
}
public void printGames(){
for(Game tempGame : games){
System.out.println(tempGame.toString());
System.out.println("");
}
}
public Game getGamesByIndex(int i){
Game tempGame = new Game();
if (i < getVectorSize()){
tempGame = games.get(i);
}
return tempGame;
}
public void sortGamesByName(){
Game currentGame = new Game();
Game nextGame = new Game();
Game tempGame = new Game();
for(int i = 0; i < getVectorSize(); i++){
for(int j = 0; j < getVectorSize()-i-1; j++){
currentGame = games.elementAt(j);
nextGame = games.elementAt(j+1);
if(currentGame.getGameName().compareTo(nextGame.getGameName())>0){
tempGame = currentGame;
games.setElementAt(nextGame, j);
games.setElementAt(tempGame, j+1);
}
}
}
}
public boolean checkGamebyGameKey(String gameKey){
boolean flag = false;
for(Game tempGames : games){
if(tempGames .getGameKey().equals(gameKey)){
flag = true;
}
}
return flag;
}
public Game accessGameByGameName(String gameName){
Game foundGameName = new Game();
for(Game tempGames: games){
if(tempGames.getGameName().equals(gameName)){
foundGameName = tempGames;
}
}
return foundGameName;
}
public void saveToFile(){
try{
File f = new File("C:/Users/Denis/Desktop/GameStore/Databases","gameList.obj");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(games);
oos.flush();
oos.close();
}catch (IOException ioe){
System.err.println("Cannot write to file!");
}
}
public void readFromFile(){
try{
File f = new File("C:/Users/Denis/Desktop/GameStore/Databases","gameList.obj");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
games = (Vector<Game>) ois.readObject();
ois.close();
} catch (FileNotFoundException fnfe){
System.err.println("Cannot find file!");
}catch (IOException ioe){
System.err.println("Cannot read from file!");
}catch(ClassNotFoundException cnfe){
System.err.println("Client class cannot be found!");
}
}
}
Main class: GameCenter
public class GameCenter extends JFrame {
public static void main(String... args) {
SwingUtilities.invokeLater(() -> new GameCenter().setVisible(true));
}
public GameCenter() {
super("Game Center");
init();
}
private void init() {
setLayout(new BorderLayout(5, 5));
Model model = new Model();
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.add("Add", new AddTabPanel(model));
tabbedPane.add("View", new ViewTabPanel(model));
add(tabbedPane, BorderLayout.CENTER);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(400, 500);
setMinimumSize(new Dimension(400, 500));
setResizable(false);
}
}
Game entity:
final class Game {
private static final Pattern RECORD = Pattern.compile("(?<key>.+)\\|(?<name>.+)\\|(?<type>.+)");
private final String name;
private final String key;
private final String type;
public static Game createFromRecord(String str) {
Matcher matcher = RECORD.matcher(str);
return matcher.matches() ? new Game(matcher.group("name"), matcher.group("key"), matcher.group("type")) : null;
}
public Game(String name, String key, String type) {
this.name = name;
this.key = key;
this.type = type;
}
public String getName() {
return name;
}
public String getKey() {
return key;
}
public String getType() {
return type;
}
public String serialize() {
return String.format("%s|%s|%s", key, name, type);
}
}
Table model:
final class Model extends AbstractTableModel {
private static final long serialVersionUID = 1858846855164475327L;
private final Map<String, Game> keyGame = new TreeMap<>();
private final List<Game> data = new ArrayList<>();
private File file;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public void add(String name, String key, String type) {
keyGame.put(key, new Game(name, key, type));
fireTableDataChanged();
}
public void remove(int rowIndex) {
keyGame.remove(data.get(rowIndex).getKey());
fireTableDataChanged();
}
public void save() throws IOException {
if (file == null)
return;
try (FileWriter out = new FileWriter(file, false)) {
for (Game game : keyGame.values())
out.write(game.serialize() + '\n');
}
}
public void read() throws IOException {
if (file == null)
return;
keyGame.clear();
for (String record : Files.readAllLines(file.toPath())) {
Game game = Game.createFromRecord(record);
if (game != null)
keyGame.put(game.getKey(), game);
}
fireTableDataChanged();
}
private enum Column {
NAME("Game Name", Game::getName),
KEY("Game Key", Game::getKey),
TYPE("Game Type", Game::getType);
private final String title;
private final Function<Game, Object> get;
Column(String title, Function<Game, Object> get) {
this.title = title;
this.get = get;
}
public Object getValue(Game game) {
return get.apply(game);
}
}
// ========== AbstractTableModel ==========
#Override
public void fireTableDataChanged() {
data.clear();
data.addAll(keyGame.values());
super.fireTableDataChanged();
}
// ========== TableModel ==========
#Override
public int getRowCount() {
return data.size();
}
#Override
public int getColumnCount() {
return Column.values().length;
}
#Override
public String getColumnName(int columnIndex) {
return Column.values()[columnIndex].title;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return Column.values()[columnIndex].getValue(data.get(rowIndex));
}
}
AddGame tab panel:
final class AddTabPanel extends JPanel implements ActionListener, DocumentListener {
private final Model model;
private final JTextField nameField = new JTextField();
private final JTextField keyField = new JTextField();
private final JLabel nameLabel = new JLabel("Game Name");
private final JLabel keyLabel = new JLabel("Game Key");
private final JLabel typeLabel = new JLabel("Game Type");
private final JComboBox<String> typeCombo = createGameTypeCombo();
private final JButton openButton = new JButton("Open");
private final JButton saveButton = new JButton("Save");
private final JButton clearButton = new JButton("Clear");
public AddTabPanel(Model model) {
this.model = model;
init();
addListeners();
}
private void init() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = createConstraints();
add(createTitlePanel(), gbc);
add(createMainPanel(), gbc);
add(createButtonPanel(), gbc);
gbc.weighty = 1;
add(Box.createVerticalGlue(), gbc);
onNameFieldChanged();
onKeyFieldChanged();
onTypeComboChanged();
}
private static JPanel createTitlePanel() {
JLabel label = new JLabel("Add a game below");
label.setFont(new Font("Verdana", Font.BOLD, 20));
JPanel panel = new JPanel();
panel.add(label);
return panel;
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(3, 2, 5, 5));
panel.add(nameLabel);
panel.add(nameField);
panel.add(keyLabel);
panel.add(keyField);
panel.add(typeLabel);
panel.add(typeCombo);
return panel;
}
private static GridBagConstraints createConstraints() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
return gbc;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel();
panel.add(clearButton);
panel.add(saveButton);
panel.add(openButton);
return panel;
}
private static JComboBox<String> createGameTypeCombo() {
JComboBox<String> combo = new JComboBox<>();
combo.setModel(new DefaultComboBoxModel<>(new String[] { "<--Select-->", "Arcade", "Puzzle", "Adventure", "Shooter", "Roleplay" }));
return combo;
}
private void addListeners() {
clearButton.addActionListener(this);
saveButton.addActionListener(this);
openButton.addActionListener(this);
nameField.getDocument().addDocumentListener(this);
keyField.getDocument().addDocumentListener(this);
typeCombo.addActionListener(this);
}
private void validateFields() {
String name = nameField.getText().trim();
String key = keyField.getText().trim();
int type = typeCombo.getSelectedIndex();
saveButton.setEnabled(!name.isEmpty() && !key.isEmpty() && type != 0);
}
private void onNameFieldChanged() {
nameLabel.setForeground(nameField.getText().trim().isEmpty() ? Color.RED : Color.BLACK);
validateFields();
}
private void onKeyFieldChanged() {
keyLabel.setForeground(keyField.getText().trim().isEmpty() ? Color.RED : Color.BLACK);
validateFields();
}
private void onTypeComboChanged() {
typeLabel.setForeground(typeCombo.getSelectedIndex() == 0 ? Color.RED : Color.BLACK);
validateFields();
}
private void onCleanButton() {
nameField.setText(null);
keyField.setText(null);
typeCombo.setSelectedIndex(0);
validateFields();
}
private void onSaveButton() {
String name = nameField.getText().trim();
String key = keyField.getText().trim();
String type = (String)typeCombo.getSelectedItem();
model.add(name, key, type);
if (model.getFile() == null) {
JFileChooser fileChooser = new JFileChooser();
int res = fileChooser.showSaveDialog(this);
model.setFile(res == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null);
}
try {
model.save();
} catch(Exception e) {
JOptionPane.showMessageDialog(this, "Cannot save file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
private void onOpenButton() {
JFileChooser fileChooser = new JFileChooser();
int res = fileChooser.showOpenDialog(null);
model.setFile(res == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null);
try {
model.read();
} catch(Exception e) {
JOptionPane.showMessageDialog(this, "Cannot read file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
// ========== ActionListener ==========
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == typeCombo)
onTypeComboChanged();
else if (e.getSource() == clearButton)
onCleanButton();
else if (e.getSource() == saveButton)
onSaveButton();
else if (e.getSource() == openButton)
onOpenButton();
}
// ========== DocumentListener ==========
#Override
public void insertUpdate(DocumentEvent e) {
if (e.getDocument() == nameField.getDocument())
onNameFieldChanged();
else if (e.getDocument() == keyField.getDocument())
onKeyFieldChanged();
}
#Override
public void removeUpdate(DocumentEvent e) {
if (e.getDocument() == nameField.getDocument())
onNameFieldChanged();
else if (e.getDocument() == keyField.getDocument())
onKeyFieldChanged();
}
#Override
public void changedUpdate(DocumentEvent e) {
}
}
ViewGame tab panel:
final class ViewTabPanel extends JPanel implements ActionListener, PopupMenuListener {
private final Model model;
private final JTable table = new JTable();
private final JPopupMenu popupMenu = new JPopupMenu();
private final JMenuItem deleteItem = new JMenuItem("Delete");
public ViewTabPanel(Model model) {
this.model = model;
init();
addListeners();
}
private void init() {
setLayout(new GridLayout(1, 1));
add(new JScrollPane(table));
popupMenu.add(deleteItem);
table.setComponentPopupMenu(popupMenu);
table.setAutoCreateRowSorter(true);
table.setModel(model);
table.updateUI();
}
private void addListeners() {
popupMenu.addPopupMenuListener(this);
deleteItem.addActionListener(this);
}
// ========== ActionListener ==========
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == deleteItem) {
model.remove(table.getSelectedRow());
try {
model.save();
} catch(Exception e) {
JOptionPane.showMessageDialog(this, "Cannot save file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
}
// ========== PopupMenuListener ==========
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
if (event.getSource() == popupMenu) {
SwingUtilities.invokeLater(() -> {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
if (rowAtPoint > -1)
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
});
}
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent event) {
}
#Override
public void popupMenuCanceled(PopupMenuEvent event) {
}
}
I am performing actions for 2 combo boxes which involves in changing the background color of JLabel. Here is my code,
public class JavaApplication8 {
private JFrame mainFrame;
private JLabel signal1;
private JLabel signal2;
private JPanel s1Panel;
private JPanel s2Panel;
public JavaApplication8()
{
try {
prepareGUI();
} catch (ClassNotFoundException ex) {
Logger.getLogger(JavaApplication8.class.getName())
.log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws
ClassNotFoundException
{
JavaApplication8 swingControl = new JavaApplication8();
swingControl.showCombobox1();
}
public void prepareGUI() throws ClassNotFoundException
{
mainFrame = new JFrame("Signal");
mainFrame.setSize(300,200);
mainFrame.setLayout(new GridLayout(3, 0));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
signal1 = new JLabel("Signal 1",JLabel.LEFT);
signal1.setSize(100,100);
signal1.setOpaque(true);
signal2 = new JLabel("Signal 2",JLabel.LEFT);
signal2.setSize(100,100);
signal2.setOpaque(true);
final DefaultComboBoxModel light = new DefaultComboBoxModel();
light.addElement("Red");
light.addElement("Green");
final JComboBox s1Combo = new JComboBox(light);
s1Combo.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae)
{
if(s1Combo.getSelectedIndex() == 0)
{
signal1.setBackground(Color.RED);
}
else
{
signal1.setBackground(Color.GREEN);
}
}
});
final JComboBox s2Combo1 = new JComboBox(light);
s2Combo1.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae)
{
if(s2Combo1.getSelectedIndex() == 0)
{
signal2.setBackground(Color.RED);
}
else
{
signal2.setBackground(Color.GREEN);
}
}
});
s1Panel = new JPanel();
s1Panel.setLayout(new FlowLayout());
JScrollPane ListScrollPane = new JScrollPane(s1Combo);
s1Panel.add(signal1);
s1Panel.add(ListScrollPane);
s2Panel = new JPanel();
s2Panel.setLayout(new FlowLayout());
JScrollPane List1ScrollPane = new JScrollPane(s2Combo1);
s2Panel.add(signal2);
s2Panel.add(List1ScrollPane);
mainFrame.add(s1Panel);
mainFrame.add(s2Panel);
String[] columnNames = {"Signal 1","Signal 2"};
Object[][] data = {{"1","1"}};
final JTable table = new JTable(data,columnNames);
JScrollPane tablepane = new JScrollPane(table);
table.setFillsViewportHeight(true);
mainFrame.add(tablepane);
mainFrame.setVisible(true);
}
}
When Executed, If I change the item from combo box 1, the 2nd combo box also performs the change. Where did I go wrong?
Yours is a simple solution: don't have the JComboBoxes share the same model. If they share the same model, then changes to the selected item of one JComboBox causes a change in the shared model which changes the view of both JComboBoxes.
I wold use a method to create your combo-jlabel duo so as not to duplicate code. For instance:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class App8 extends JPanel {
private static final int COMBO_COUNT = 2;
private static final String SIGNAL = "Signal";
private List<JComboBox<ComboColor>> comboList = new ArrayList<>();
public App8() {
setLayout(new GridLayout(0, 1));
for (int i = 0; i < COMBO_COUNT; i++) {
DefaultComboBoxModel<ComboColor> cModel = new DefaultComboBoxModel<>(ComboColor.values());
JComboBox<ComboColor> combo = new JComboBox<>(cModel);
add(createComboLabelPanel((i + 1), combo));
comboList.add(combo);
}
}
private JPanel createComboLabelPanel(int index, final JComboBox<ComboColor> combo) {
JPanel panel = new JPanel();
final JLabel label = new JLabel(SIGNAL + " " + index);
label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
label.setOpaque(true);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
ComboColor cColor = (ComboColor) combo.getSelectedItem();
label.setBackground(cColor.getColor());
}
});
panel.add(label);
panel.add(combo);
return panel;
}
private static void createAndShowGui() {
App8 mainPanel = new App8();
JFrame frame = new JFrame("App8");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum ComboColor {
RED("Red", Color.RED),
GREEN("Green", Color.GREEN);
private String text;
private Color color;
public String getText() {
return text;
}
public Color getColor() {
return color;
}
private ComboColor(String text, Color color) {
this.text = text;
this.color = color;
}
#Override
public String toString() {
return text;
}
}
I need a Jtable having Add Button on the header.When add is clicked..then it must add a row containing 4 columns of 3 textfields and delete button. When delete button is clicked, then the corresponding row should deleted.. Thanks in advance..
public class UserTableInfo {
private JFrame frame;
private JTable CompTable = null;
private PanelTableModel CompModel = null;
private JButton delButton=null;
private JButton button=null;
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception fail) {
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new UserTableInfo().makeUI();
}
}); }
public void makeUI() {
CompTable = CreateCompTable();
JScrollPane CompTableScrollpane = new JScrollPane(CompTable,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JPanel bottomPanel = CreateBottomPanel();
frame = new JFrame("Comp Table Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(CompTableScrollpane, BorderLayout.CENTER);
frame.add(bottomPanel, BorderLayout.SOUTH);
frame.setPreferredSize(new Dimension(800, 400));
frame.setLocation(150, 150);
frame.pack();
frame.setVisible(true);
}public JTable CreateCompTable() {
CompModel = new PanelTableModel();
button=new JButton("Add Row");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CompModel.addRow();
}
});
JTable table = new JTable(CompModel);
table.setRowHeight(new CompCellPanel().getPreferredSize().height);
JTableHeader header = table.getTableHeader();
header.setLayout(new FlowLayout(FlowLayout.TRAILING, 5, 0));
header.add(button);
PanelCellEditorRenderer PanelCellEditorRenderer = new
PanelCellEditorRenderer();
table.setDefaultRenderer(Object.class, PanelCellEditorRenderer);
table.setDefaultEditor(Object.class, PanelCellEditorRenderer);
return table;
} public JPanel CreateBottomPanel() {
delButton=new JButton("Exit");
delButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (source == delButton) {
System.exit(1);
}
}
}); JPanel panel = new JPanel(new GridBagLayout());
panel.add(delButton);
return panel;
}
}
class PanelCellEditorRenderer extends AbstractCellEditor implements
TableCellRenderer, TableCellEditor {
private static final long serialVersionUID = 1L;
private CompCellPanel renderer = new CompCellPanel();
private CompCellPanel editor = new CompCellPanel();
#Override
public Component getTableCellRendererComponent(JTable table, Object
value, boolean isSelected, boolean hasFocus, int row, int column) {
renderer.setComp((Comp) value);
return renderer;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object
value, boolean isSelected, int row, int column) {
editor.setComp((Comp) value);
return editor;
}
#Override
public Object getCellEditorValue() {
return null;
}
#Override
public boolean isCellEditable(EventObject anEvent) {
return true;
}
#Override
public boolean shouldSelectCell(EventObject anEvent) {
return false;
}
}
class PanelTableModel extends DefaultTableModel {
private static final long serialVersionUID = 1L;
#Override
public int getColumnCount() {
return 1;
}
public void addRow() {
super.addRow(new Object[]{new Comp("")});
}
}
class Comp {
public String upper;
public Comp(String upper) {
this.upper = upper;
}
}
class CompCellPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JLabel label = new JLabel();
private JTextField upperField = new JTextField();
private JButton removeButton = new JButton("remove");
CompCellPanel() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
removeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JTable table = (JTable)
SwingUtilities.getAncestorOfClass(JTable.class, (Component) e.getSource());
int row = table.getEditingRow();
table.getCellEditor().stopCellEditing();
((DefaultTableModel) table.getModel()).removeRow(row);
} });
upperField.setMaximumSize(new Dimension(Integer.MAX_VALUE, upperField.getPreferredSize().height) );
add(upperField);
label.setMaximumSize(getMaximumSize());
add(label);
add(Box.createHorizontalStrut(10));
add(removeButton);
}
public void setComp(Comp Comp) {
upperField.setText(Comp.upper);
} }
This is much easier if you extend a AbstractTableModel and use that to display your data. You can make an ArrayList of your data and add/remove from that. The TableModel will update the Table automatically when the ArrayList is changed. The ArrayList contains a class which has all the data that you would have in a row. See the Java Tutorials example from Oracle: http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TableDemoProject/src/components/TableDemo.java
For custom cells, you can detect from the TableModel which column the cell is in and update its content accordingly.
I'm adding a string to a JList with DefaultListModel and it takes seconds to appear. Sometimes, I may have to click on the JList to have the list appear.
I'm using Eclipse Indigo. When I set a breakpoint after adding the element to JList, execution is fast.
I searched the web and SO for JList slow and they all talk about adding many items to the list. I'm adding the first element to the list.
Here's my code fragments:
private DefaultListModel function_list_model = new DefaultListModel();
private JList list_functions = new JList(function_list_model);
//...
// Initialization code:
JPanel panel_function_list = new JPanel();
panel_function_list.setBounds(10, 53, 541, 220);
panel_functions.add(panel_function_list);
panel_function_list.setLayout(null);
JLabel lblFunctions = new JLabel("Functions");
lblFunctions.setHorizontalAlignment(SwingConstants.CENTER);
lblFunctions.setBounds(235, 11, 99, 14);
panel_function_list.add(lblFunctions);
list_functions.setBorder(new LineBorder(new Color(0, 0, 0)));
list_functions.setBounds(10, 42, 492, 177);
list_functions.setFont(new Font("Courier New", Font.PLAIN, 12));
list_functions.setPreferredSize(new Dimension(0, 150));
list_functions.setMinimumSize(new Dimension(32767, 100));
list_functions.setMaximumSize(new Dimension(32767, 100));
JScrollPane scrollPane_functions = new JScrollPane(list_functions);
scrollPane_functions.setBounds(10, 79, 541, 183);
panel_functions.add(scrollPane_functions);
// Code to add a string:
String burger = new String("burger");
function_list_model.addElement(burger);
I'm also using WindowBuilder with Eclipse.
So how do I improve the performance of JList?
if you want I can to generating new Item from Char[] and to call doClick() for JButton("Fire")
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import javax.swing.*;
import javax.swing.event.*;
public class ListDemo extends JPanel implements ListSelectionListener {
private JList list;
private DefaultListModel listModel;
private static final String hireString = "Hire";
private static final String fireString = "Fire";
private JButton fireButton;
private JTextField employeeName;
private javax.swing.Timer timer = null;
private int delay = 3;
private int count = 0;
public ListDemo() {
super(new BorderLayout());
listModel = new DefaultListModel();
listModel.addElement("Jane Doe");
listModel.addElement("John Smith");
listModel.addElement("Kathy Green");
list = new JList(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.addListSelectionListener(this);
list.setVisibleRowCount(5);
JScrollPane listScrollPane = new JScrollPane(list);
JButton hireButton = new JButton(hireString);
HireListener hireListener = new HireListener(hireButton);
hireButton.setActionCommand(hireString);
hireButton.addActionListener(hireListener);
hireButton.setEnabled(false);
fireButton = new JButton(fireString);
fireButton.setActionCommand(fireString);
fireButton.addActionListener(new FireListener());
employeeName = new JTextField(10);
employeeName.addActionListener(hireListener);
employeeName.getDocument().addDocumentListener(hireListener);
String name = listModel.getElementAt(list.getSelectedIndex()).toString();
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
buttonPane.add(fireButton);
buttonPane.add(Box.createHorizontalStrut(5));
buttonPane.add(new JSeparator(SwingConstants.VERTICAL));
buttonPane.add(Box.createHorizontalStrut(5));
buttonPane.add(employeeName);
buttonPane.add(hireButton);
buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
add(listScrollPane, BorderLayout.CENTER);
add(buttonPane, BorderLayout.PAGE_END);
start();
System.out.println(new Date());
}
private void start() {
timer = new javax.swing.Timer(delay * 10, updateCol());
timer.start();
}
public Action updateCol() {
return new AbstractAction("text load action") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
listModel.addElement("Jane Doe");
listModel.addElement("John Smith");
listModel.addElement("Kathy Green");
list.ensureIndexIsVisible(listModel.getSize()-1);
count++;
if (count >= 500) {
timer.stop();
System.out.println("update cycle completed");
System.out.println(new Date());
}
}
};
}
class FireListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int index = list.getSelectedIndex();
listModel.remove(index);
int size = listModel.getSize();
if (size == 0) { //Nobody's left, disable firing.
fireButton.setEnabled(false);
} else { //Select an index.
if (index == listModel.getSize()) {
index--;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
}
}
class HireListener implements ActionListener, DocumentListener {
private boolean alreadyEnabled = false;
private JButton button;
HireListener(JButton button) {
this.button = button;
}
#Override
public void actionPerformed(ActionEvent e) {
String name = employeeName.getText();
if (name.isEmpty() || alreadyInList(name)) {
Toolkit.getDefaultToolkit().beep();
employeeName.requestFocusInWindow();
employeeName.selectAll();
return;
}
int index = list.getSelectedIndex(); //get selected index
if (index == -1) { //no selection, so insert at beginning
index = 0;
} else { //add after the selected item
index++;
}
listModel.insertElementAt(employeeName.getText(), index);
//listModel.addElement(employeeName.getText());
employeeName.requestFocusInWindow();
employeeName.setText("");
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
protected boolean alreadyInList(String name) {
return listModel.contains(name);
}
#Override
public void insertUpdate(DocumentEvent e) {
enableButton();
}
#Override
public void removeUpdate(DocumentEvent e) {
handleEmptyTextField(e);
}
#Override
public void changedUpdate(DocumentEvent e) {
if (!handleEmptyTextField(e)) {
enableButton();
}
}
private void enableButton() {
if (!alreadyEnabled) {
button.setEnabled(true);
}
}
private boolean handleEmptyTextField(DocumentEvent e) {
if (e.getDocument().getLength() <= 0) {
button.setEnabled(false);
alreadyEnabled = false;
return true;
}
return false;
}
}
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) {
fireButton.setEnabled(false);
} else {
fireButton.setEnabled(true);
}
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("ListDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new ListDemo();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}
I am trying to add horizontal scroll bar in a JComboBox using reference with thread - Horizontal scrollbar for JComboBox across multiple look and feel at the OTN, but it's not working in my case.
How to add a horizontal scroll bar to JComboBox correctly?
Code -
public class TestJComboBoxWithScrollBar {
TestJComboBoxWithScrollBar() {
JDialog jDialog = new JDialog();
jDialog.setTitle("Test JComboBox With ScrollBar");
JPanel jPanel_Sort = new JPanel();
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints bagConstraints = new GridBagConstraints();
jPanel_Sort.setLayout(gbl);
bagConstraints.gridwidth = 1;
bagConstraints.gridheight = 1;
bagConstraints.fill = GridBagConstraints.NONE;
bagConstraints.anchor = GridBagConstraints.WEST;
bagConstraints.weightx = 0;
bagConstraints.weighty = 0;
bagConstraints.insets = new Insets(5, 5, 5, 5);
bagConstraints.gridx = 0;
bagConstraints.gridy = 0;
SampleJComboBoxWithScrollBar cmbHeaders = new SampleJComboBoxWithScrollBar();
cmbHeaders.addItem("aaaaaaaaaaaaa");
cmbHeaders.addItem("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
cmbHeaders.setPreferredSize(new Dimension(190, 50));
cmbHeaders.setMinimumSize(new Dimension(190, 50));
cmbHeaders.setMaximumSize(new Dimension(190, 50));
jPanel_Sort.add(cmbHeaders, bagConstraints);
JCheckBox chkOrderBy = new JCheckBox("Asc");
bagConstraints.gridx = 1;
bagConstraints.gridy = 0;
jPanel_Sort.add(chkOrderBy, bagConstraints);
jPanel_Sort.setPreferredSize(new Dimension(220, 70));
jPanel_Sort.setMinimumSize(new Dimension(220, 70));
jPanel_Sort.setMaximumSize(new Dimension(220, 70));
jDialog.add(jPanel_Sort, BorderLayout.CENTER);
jDialog.setPreferredSize(new Dimension(300, 100));
jDialog.pack();
jDialog.setResizable(false);
jDialog.setModal(true);
jDialog.setVisible(true);
}
public static void main(String[] argu) {
new TestJComboBoxWithScrollBar();
}
class SampleJComboBoxWithScrollBar extends JComboBox {
SampleJComboBoxWithScrollBar() {
super();
this.addPopupMenuListener(this.getPopupMenuListener());
this.adjustScrollBar();
}
private void adjustPopupWidth() {
if (getItemCount() == 0) {
return;
}
Object comp = getUI().getAccessibleChild(this, 0);
if (!(comp instanceof JPopupMenu)) {
return;
}
JPopupMenu popup = (JPopupMenu) comp;
JScrollPane scrollPane = (JScrollPane) popup.getComponent(0);
Object value = getItemAt(0);
Component rendererComp = getRenderer().getListCellRendererComponent(new JList(), value, 0, false, false);
if (rendererComp instanceof JXTable) {
scrollPane.setColumnHeaderView(((JTable) rendererComp).getTableHeader());
}
Dimension prefSize = rendererComp.getPreferredSize();
Dimension size = scrollPane.getPreferredSize();
size.width = Math.max(size.width, prefSize.width);
scrollPane.setPreferredSize(size);
scrollPane.setMaximumSize(size);
scrollPane.revalidate();
}
private void adjustScrollBar() {
if (getItemCount() == 0) {
return;
}
Object comp = getUI().getAccessibleChild(this, 0);
if (!(comp instanceof JPopupMenu)) {
return;
}
JPopupMenu popup = (JPopupMenu) comp;
JScrollPane scrollPane = (JScrollPane) popup.getComponent(0);
scrollPane.setHorizontalScrollBar(new JScrollBar(JScrollBar.HORIZONTAL));
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
private PopupMenuListener getPopupMenuListener() {
return new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
adjustPopupWidth();
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
};
}
}
}
if you meaning code posted by #Kleopatra then void adjustScrollBar() never will be called from PopupMenuListener
private PopupMenuListener getPopupMenuListener() {
return new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
//adjustPopupWidth();
adjustScrollBar();
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
};
}