Well I'm making a simple program to see how works swing elements. Main problem is that when I change the data of table's model not updates the view. I'm using MVP and I've tried "fireTableDataChanged", "fireTableStructureChanged", "repaint", "validate"...
So here's the presenter with "registerStudent" method:
public class StudentPresenter {
private List<Student> students;
private StudentView view;
public StudentPresenter(StudentView view) {
students = new ArrayList<>();
this.view = view;
}
public void run() {
JFrame frame = new JFrame("Students Registrator");
frame.setContentPane(view.getMainFrame());
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void registerStudent() {
students.add(new Student("Nuevo", 1, 2));
students.add(new Student("Otro", 3, 4));
((TableModel) view.getTable().getModel()).setData(students);
((TableModel) view.getTable().getModel()).refresh();
view.getTable().repaint();
}
}
TableModel with "refresh" method:
public class TableModel extends AbstractTableModel {
private String[] columnNames = {"Nombre", "Edad", "Curso"};
private List<Student> data = new ArrayList<>();
public TableModel() {
data.add(new Student("Ejemplo", 0, 0));
}
public void setData(List<Student> data) {
this.data = data;
}
public void refresh() {
fireTableDataChanged();
}
#Override
public int getRowCount() {
return data.size();
}
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public String getColumnName(int column) {
return columnNames[column];
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch(columnIndex) {
case 0:
return data.get(rowIndex).getName();
case 1:
return data.get(rowIndex).getAge();
case 2:
return data.get(rowIndex).getCourse();
default:
return null;
}
}
}
StudentView:
public class StudentView {
private StudentPresenter presenter;
private JMenuBar menuBar;
private JScrollPane scrollPane;
private JPanel mainFrame;
private JTable table;
private JButton registerButton;
public StudentView() {
createUIComponents();
}
private void createUIComponents() {
buildMenu();
buildButtons();
buildTable();
}
private void buildMenu() {
menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem exitItem = new JMenuItem("Salir");
exitItem.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
fileMenu.add(exitItem);
JMenu editMenu = new JMenu("Edit");
menuBar.add(fileMenu);
menuBar.add(editMenu);
}
private void buildButtons() {
registerButton = new JButton();
registerButton.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
presenter.registerStudent();
}
});
}
private void buildTable() {
table = new JTable(new TableModel());
table.setFillsViewportHeight(true);
table.setBackground(Color.LIGHT_GRAY);
table.setForeground(Color.gray);
table.setFont(new Font("Arial", Font.PLAIN, 12));
table.setRowHeight(30);
scrollPane = new JScrollPane(table);
}
public void setPresenter(StudentPresenter presenter) {
this.presenter = presenter;
}
public JPanel getMainFrame() {
return mainFrame;
}
public JTable getTable() {
return table;
}
}
Related
I am new to java swing. I am creating application for patient registration using Swing. There is a button called Clear, that button should clear the input data from the text fields.When button is InputPanel.clear() set the values correctly.But it is not updating.
My classes are below.
MainWindow class create and show the GUI.
public class MainWindow extends JFrame implements ActionListener {
private static final long serialVersionUID = 1905122041950251207L;
transient TableRowSorter<PatientTableModel> sorter;
private PatientListView patientListViewPanel = new PatientListView();
private InputPanel inputPanel = new InputPanel();
private SearchCriteriaPanel searhCriteriaPanel = new SearchCriteriaPanel(this);
public void createAndShowGUI() {
ButtonPanel btnPanel = new ButtonPanel(new MainWindow());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
sorter = new TableRowSorter<>(patientListViewPanel.getTableModel());
GridBagLayout gbl = new GridBagLayout();
this.setLayout(gbl);
GridBagConstraints gcon = new GridBagConstraints();
gcon.weightx = 1;
gcon.weighty = 5;
gcon.fill = GridBagConstraints.BOTH;
gcon.gridx = 0;
gcon.gridy = 0;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(inputPanel, gcon);
this.add(inputPanel);
gcon.gridx = 4;
gcon.gridy = 10;
gcon.gridwidth = 11;
gcon.gridheight = 5;
gbl.setConstraints(btnPanel, gcon);
this.add(btnPanel);
gcon.gridx = 0;
gcon.gridy = 22;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(searhCriteriaPanel, gcon);
this.add(searhCriteriaPanel);
gcon.gridx = 0;
gcon.gridy = 33;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(patientListViewPanel, gcon);
this.add(patientListViewPanel);
this.setVisible(true);
inputPanel.getNameText().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (inputPanel.getNameText().getText().length() > 0)
btnPanel.getSaveBtn().setEnabled(true);
}
});
patientListViewPanel.getTable().addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
getSelectedData();
}
});
}
public MainWindow() {
super("Patient Registration");
}
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
switch (button.getText()) {
case "Save":
patientListViewPanel.getTableModel()
.addData(inputPanel.getData(patientListViewPanel.getTable().getRowCount()));
button.setEnabled(false);
break;
case "Clear":
inputPanel.clear();
break;
case "Search":
SearchCriteria s = new SearchCriteria(searhCriteriaPanel.getSearchNameText().getText(),
searhCriteriaPanel.getBirthYearText().getText(), searhCriteriaPanel.getMaleChkBx().isSelected(),
searhCriteriaPanel.getFemaleChkBx().isSelected());
patientListViewPanel.filter(s);
break;
default:
}
}
}
InputPanel is handle the fields and methods related to input data
public class InputPanel extends JPanel implements PropertyChangeListener {
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(" ");
phnText.setText("0");
datePickerObj.jDatePicker.getJFormattedTextField().setText("");
maleBtn.setSelected(true);
femaleBtn.setSelected(false);
adrsTxt.setText("");
statusList.setSelectedIndex(4);
}
public InputPanel() {
// fiels will be set to panel
addDataChangedListner();
isDataValid(phnText);
}
public void addDataChangedListner() {
PatientData model = new PatientData();
model.addPropertyChangeListener(this);
nameText.getDocument().addDocumentListener(new DataChangedListener(model, "name"));
phnText.getDocument().addDocumentListener(new DataChangedListener(model, "phnNumber"));
adrsTxt.getDocument().addDocumentListener(new DataChangedListener(model, "address"));
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
String property = evt.getPropertyName();
String newValue = (String) evt.getNewValue();
switch (property) {
case "name":
updatedName = newValue;
break;
case "phnNumber":
updatedPhoneNumber = newValue;
break;
case "address":
updatedAddress = newValue;
break;
default:
}
}
}
Can someone help me to resolve this?
The basic functionality that you are having difficulty with is demonstrated in the following mre: (1)
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MainWindow extends JFrame{
private InputPanel inputPanel;
private JButton saveBtn;
public void createAndShowGUI() {
inputPanel = new InputPanel();
saveBtn = new JButton("Save");
saveBtn.setEnabled(false);
add(saveBtn, BorderLayout.SOUTH);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(e->clearInput());
add(clearButton, BorderLayout.CENTER);
add(inputPanel, BorderLayout.NORTH);
inputPanel.getNameText().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (inputPanel.getNameText().getText().length() > 0) {
saveBtn.setEnabled(true);
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void clearInput(){
inputPanel.clear();
saveBtn.setEnabled(false);
}
public MainWindow() {
createAndShowGUI();
}
public static void main(String[] args) {
new MainWindow();
}
}
class InputPanel extends JPanel {
JTextField nameText;
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(""); //use "" and not " " so text length = 0
}
public InputPanel() {
nameText = new JTextField(5);
add(nameText);
}
public JTextField getNameText() {
return nameText;
}
}
However, a better approach is to use the model to implement the change of data :
public class MainWindow extends JFrame implements PropertyChangeListener{
private InputPanel inputPanel;
private JButton saveBtn;
private final PatientData model;
public void createAndShowGUI() {
inputPanel = new InputPanel(model);
saveBtn = new JButton("Save");
saveBtn.setEnabled(false);
add(saveBtn, BorderLayout.SOUTH);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(e->clearInput());
add(clearButton, BorderLayout.CENTER);
add(inputPanel, BorderLayout.NORTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void clearInput(){
inputPanel.clear();
}
public MainWindow() {
model = new PatientData();
model.setPropertyChangeListener(this);
createAndShowGUI();
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
updateGui();
}
private void updateGui() {
if(model.getName().trim().isEmpty()){
saveBtn.setEnabled(false);
}else{
saveBtn.setEnabled(true);
}
}
public static void main(String[] args) {
new MainWindow();
}
}
class InputPanel extends JPanel implements DocumentListener{
private final JTextField nameText;
private final PatientData model;
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(""); //use "" and not " " so text length = 0
updateModel();
}
public InputPanel(PatientData model) {
this.model = model;
nameText = new JTextField("",5);
nameText.getDocument().addDocumentListener(this);
add(nameText);
}
#Override
public void changedUpdate(DocumentEvent e) {
updateModel();
}
#Override
public void removeUpdate(DocumentEvent e) {
updateModel();
}
#Override
public void insertUpdate(DocumentEvent e) {
updateModel();
}
private void updateModel() {
model.setName(nameText.getText());
}
}
class PatientData{
private String name ="";
private PropertyChangeListener listener;
public String getName() {
return name;
}
public void setPropertyChangeListener(PropertyChangeListener listener) {
this.listener = listener;
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
if(listener != null) {
listener.propertyChange(new PropertyChangeEvent(this,"name", oldName, name));
}
}
}
(Test is online here)
(1) Always consider an mre when posting a question or answer.
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;
}
}
The JDialog isn't showing the JPanel after closing of the dialog and then if the user immediately repeats the action it isn't showing a panel at all but a dialog that is solid black with a small white box in the top left corner. I have tried creating a SSCCE but couldn't develop one. If I remove the window adapter in MainControl class it will just keep adding another panel to the dialog after closing and repeating the opening of the dialog. Below is the code of the SSCCE that I tried creating but it still behaves the same. The code below is the minimal amount needed to run the dialog.
public class CreateAndShowUI {
public static void createUI() {
JFrame frame = new JFrame();
MainPanel mainPanel = new MainPanel();
Dialog dialog = new Dialog();
MainControl mainControl = new MainControl(frame, mainPanel,
dialog);
frame.getContentPane().add(mainPanel.getMainPanel());
frame.setUndecorated(true);
frame.setPreferredSize(new Dimension(1100, 550));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
createUI();
}
}
public class MainControl {
private JFrame frame;
private MainPanel mainPanel;
private Dialog dialog;
public MainControl(JFrame frame, MainPanel panel, Dialog dialog) {
this.frame = frame;
this.mainPanel = panel;
this.dialog = dialog;
mainPanel.getTable().addMouseListener(new MouseListener());
dialog.getDialog().addWindowListener(new DialogWindowListener());
}
public class MouseListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent evt) {
if (evt.getButton() == MouseEvent.BUTTON3) {
dialog.showDialog(new KeywordPanel().getKeywordPanel(),
evt.getXOnScreen(), evt.getYOnScreen());
}
}
}
public class DialogWindowListener extends WindowAdapter {
#Override
public void windowClosing(final WindowEvent event) {
dialog.getDialog().dispose();
dialog.getDialog().removeAll();
}
}
}
public class MainPanel {
private JPanel mainPanel;
private JScrollPane listScrollPane;
private JTable table;
public MainPanel() {
mainPanel = new JPanel(new MigLayout("", "", "[]13[]"));
table = new JTable(new ProductTableModel());
listScrollPane = new JScrollPane(table,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
listScrollPane.setPreferredSize(new Dimension(850, 990));
mainPanel.add(listScrollPane, "cell 0 1");
}
public JPanel getMainPanel() {
return mainPanel;
}
public JTable getTable() {
return table;
}
}
public class KeywordPanel {
private JPanel keywordPanel;
private JLabel searchLbl;
public KeywordPanel() {
searchLbl = new JLabel("KeyWords");
keywordPanel = new JPanel();
keywordPanel.add(searchLbl);
}
public JPanel getKeywordPanel() {
return keywordPanel;
}
}
public class Dialog {
private JDialog dialog = new JDialog();
public Dialog() {
dialog.setLayout(new MigLayout());
}
public void showDialog(JPanel panel, int x, int y) {
dialog.add(panel);
dialog.pack();
dialog.setVisible(true);
}
public JDialog getDialog() {
return dialog;
}
}
public class ProductTableModel extends AbstractTableModel {
private ArrayList<Object> list = new ArrayList<Object>();
private String[] columnNames = { "ID", "Description", "Inventory",
"Minimum Quantity", "Cost", "Order Quantity" };
public ProductTableModel() {
list.add(new Product("Sup", "Sup", "Sup", 10, 20, "null"));
}
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "<html>ID<br></html>";
case 1:
return "<html>Description<br></html>";
case 2:
return "<html>Inventory<br></html>";
case 3:
return "<html>Minimum<br>Quantity</html>";
case 4:
return "<html>Cost<br></html>";
case 5:
return "<html>Order<br>Quantity</html>";
default:
return null;
}
}
#Override
public int getRowCount() {
return list.size();
}
#Override
public boolean isCellEditable(int row, int column) {
return true;
}
#Override
public Object getValueAt(int row, int column) {
if (list.get(row) instanceof Product) {
Product product = (Product) list.get(row);
switch (column) {
case 0:
return product.getId();
case 1:
return product.getProductDescription();
case 2:
return product.getQtyOnHand();
case 3:
return product.getMinQty();
case 4:
return product.getCost();
case 5:
return product.getOrderQty();
default:
throw new IndexOutOfBoundsException();
}
} else {
return null;
}
}
}
public class Product {
private int minQty;
private double cost;
private String productDescription, id, category, qtyOnHand, orderQty;
public Product(String id, String productDescription, String qtyOnHand,
int minQty, double cost, String orderQty) {
this.setQtyOnHand(qtyOnHand);
this.setOrderQty(orderQty);
this.setId(id);
this.setMinQty(minQty);
this.setCost(cost);
this.setProductDescription(productDescription);
}
public String getQtyOnHand() {
return qtyOnHand;
}
public void setQtyOnHand(String qtyOnHand) {
this.qtyOnHand = qtyOnHand;
}
public String getOrderQty() {
return orderQty;
}
public void setOrderQty(String orderQty) {
this.orderQty = orderQty;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getCost() {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
public String getProductDescription() {
return productDescription;
}
public void setProductDescription(String productDescription) {
this.productDescription = productDescription;
}
public int getMinQty() {
return minQty;
}
public void setMinQty(int minQty) {
this.minQty = minQty;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
You should use
dialog.getContentPane().add(panel);
and
dialog.getDialog().getContentPane().removeAll();
And you also must NOT dispose the dialog,
I have JTable which shows data from arraylist through AbstractTableModel.
What I want to do is when I click (left-click) on row in JTable, I want to show new window where can I see and edit data from row stored in arraylist.
I have MouseListener already written, but it does nothing.
There are main,table and tablemodel classes.
public class MainWindow extends JFrame {
private Controller controller;
private Prihlasovanie prihlasovanie;
private TabulkaSkladnik tabulkaskladnik;
private Okno okno;
public MainWindow() {
super("PROJEKT OOP");
setVisible(true);
setSize(750, 508);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
setMinimumSize(new Dimension(800,500));
controller = new Controller();
tabulkaskladnik = new TabulkaSkladnik();
prihlasovanie = new Prihlasovanie();
tabulkaskladnik.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Okno okno = new Okno();
okno.setVisible(true);
}
});
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
getContentPane().add(tabbedPane, BorderLayout.NORTH);
tabbedPane.addTab("Prihlasovanie", null , prihlasovanie , null);
tabbedPane.addTab("Skladnik", null , tabulkaskladnik , null);
tabulkaskladnik.setData(controller.getObjednavky());
}
}
public class TabulkaSkladnik extends JTable {
private JTable tabulka;
private SkladnikTableModel tabulkaModel;
public TabulkaSkladnik() {
tabulkaModel = new SkladnikTableModel();
tabulka = new JTable(tabulkaModel);
setLayout(new BorderLayout());
add(new JScrollPane(tabulka),BorderLayout.CENTER);
}
public void setData(List<Objednavka> databaza) {
tabulkaModel.setData(databaza);
}
public void refresh() {
tabulkaModel.fireTableDataChanged();
}
}
public class SkladnikTableModel extends AbstractTableModel {
private List<Objednavka> databaza;
private String[] colNames = {"ID", "Nazov", "Popis", "Meno", "Priezvisko"};
public SkladnikTableModel() {
}
public void setData(List<Objednavka> databaza) {
this.databaza = databaza;
}
public String getColumnName(int column) {
// TODO Auto-generated method stub
return colNames[column];
}
public Class getColumnClass(int col) {
return getValueAt(0,col).getClass();
}
#Override
public int getColumnCount() {
// TODO Auto-generated method stub
return 5;
}
#Override
public int getRowCount() {
return databaza.size();
}
#Override
public Object getValueAt(int riadok, int stlpec) {
Objednavka objednavka = databaza.get(riadok);
switch(stlpec) {
case 0: return objednavka.getId();
case 1: return objednavka.getNazov();
case 2: return objednavka.getOpis();
case 3: return objednavka.getMeno();
case 4: return objednavka.getPriezvisko();
}
return null;
}
}
Thank you for your help! :)
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.