Java: JComboBox selection issue on image - java

In this GUI there are four images which place on array of DefaultComboBoxModel and label which helps to display the image. The default image is 1.png which appear on the frame. But when I select the other image from the combo list then it doesn't appear.
Code
public class Combo extends JFrame {
public Combo() {
super("Combo 2 GUI");
setSize(400, 300);
MethodG();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
private void MethodG() {
JLabel l1;
JComboBox box;
JPanel p;
Container pane = getContentPane();
p = new JPanel();
box = new JComboBox();
box.setModel(new DefaultComboBoxModel(new String[] { "1.png", "2.png", "3.png", "4.png" }));
box.setMaximumRowCount(3);
String boxoption = (String) box.getSelectedItem();
Icon[] icons = { new ImageIcon(getClass().getResource(boxoption)) };
// Default display
l1 = new JLabel(icons[0]);
box.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
l1.setIcon(icons[box.getSelectedIndex()]);
}
}
});
pane.add(p);
p.add(box);
p.add(l1);
}
}
Main method
public class Main {
public static void main(String[] args) {
Combo obj = new Combo();
}
}
And the second problem what does these two lines do and how to write in if syntax.
JComboBox schemaBox;
String schema = (schemaBox.isEnabled() ? schemaBox.getSelectedItem().toString() : null);
String selectTable = (schema == null ? "" : schema + ".") + tableName;

To the first question: You have (easiest or ways) to get the icon or image icon directly from DefaultComboBoxModel, for example,
.
.
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
public class ComboBoxModels {
private JComboBox comboBoxDouble;
private JComboBox comboBoxInteger;
private JComboBox comboBoxBoolean;
private JComboBox comboBoxIcon;
private JComboBox comboBoxDate;
private JLabel label = new JLabel();
private Vector<Double> doubleVector = new Vector<Double>();
private Vector<Integer> integerVector = new Vector<Integer>();
private Vector<Boolean> booleanVector = new Vector<Boolean>();
private Vector<Icon> iconVector = new Vector<Icon>();
private Vector<Date> dateVector = new Vector<Date>();
private Icon icon1 = ((UIManager.getIcon("OptionPane.errorIcon")));
private Icon icon2 = (UIManager.getIcon("OptionPane.informationIcon"));
private Icon icon3 = (UIManager.getIcon("OptionPane.warningIcon"));
private Icon icon4 = (UIManager.getIcon("OptionPane.questionIcon"));
private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
public ComboBoxModels() {
doubleVector.addElement(1.001);
doubleVector.addElement(10.00);
doubleVector.addElement(0.95);
doubleVector.addElement(4.2);
comboBoxDouble = new JComboBox(doubleVector);
integerVector.addElement(1);
integerVector.addElement(2);
integerVector.addElement(3);
integerVector.addElement(4);
comboBoxInteger = new JComboBox(integerVector);
booleanVector.add(Boolean.TRUE);
booleanVector.add(Boolean.FALSE);
comboBoxBoolean = new JComboBox(booleanVector);
iconVector.addElement(icon1);
iconVector.addElement(icon2);
iconVector.addElement(icon3);
iconVector.addElement(icon4);
comboBoxIcon = new JComboBox(iconVector);
comboBoxIcon.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
Icon icon = (Icon) comboBoxIcon.getModel().getSelectedItem();
label.setIcon(icon);
}
}
});
dateVector.addElement(parseDate("25.01.2013"));
dateVector.addElement(parseDate("01.02.2013"));
dateVector.addElement(parseDate("03.03.2013"));
dateVector.addElement(parseDate("18.04.2013"));
comboBoxDate = new JComboBox(dateVector);
comboBoxDate.setRenderer(new ComboBoxRenderer());
JFrame frame = new JFrame("");
frame.setLayout(new GridLayout(2, 2, 5, 5));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(comboBoxDouble);
frame.add(comboBoxInteger);
frame.add(comboBoxBoolean);
frame.add(comboBoxIcon);
frame.add(comboBoxDate);
frame.add(label);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private Date parseDate(String str) {
Date date = new Date();
try {
date = sdf.parse(str);
} catch (ParseException ex) {
}
return date;
}
private class ComboBoxRenderer extends JLabel implements ListCellRenderer {
private static final long serialVersionUID = 1L;
public ComboBoxRenderer() {
setOpaque(true);
setBorder(new EmptyBorder(1, 1, 1, 1));
}
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
if (!(value instanceof Date)) {
return this;
}
setText(sdf.format((Date) value));
return this;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ComboBoxModels comboBoxModel = new ComboBoxModels();
}
});
}
}

Your icons array isn't being initialized as you expect. The code you have is creating an array with only one entry - 1.png. You'll need to initialize your array to contain all the images. Something like this:
Icon[] icons = { new ImageIcon(getClass().getResource("1.png")),
new ImageIcon(getClass().getResource("2.png")),
new ImageIcon(getClass().getResource("3.png")),
new ImageIcon(getClass().getResource("4.png"))};

Related

In JTabbedPane, I have two panels where same textfield and label are not displayed when written

I wanted to display same textfield and label in both the panels that are added to JTabbedPane but one of panel is displaying the textfield and label and the other is not, when added the same textfield and label for both the panels.
You can only display a component in one container. Better to have your JPanels share the same model, which for the JTextField is its Document, and for the JLabel -- well its text (not really a model that you can extract, so you'll have to change both yourself).
A bit overconvoluted example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
#SuppressWarnings("serial")
public class SharedModels extends JPanel {
private static final int TABS = 10;
private JTabbedPane tabbedPane = new JTabbedPane();
private JTextField labelText = new JTextField(10);
private MyModel myModel = new MyModel();
public SharedModels() {
for (int i = 0; i < TABS; i++) {
MyPanel myPanel = new MyPanel(myModel);
String text = "tab: " + (i + 1);
tabbedPane.addTab(text, myPanel);
}
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Text for JLabel:"));
topPanel.add(labelText);
labelText.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
setLabelText(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
setLabelText(e);
}
#Override
public void changedUpdate(DocumentEvent e) {
setLabelText(e);
}
private void setLabelText(DocumentEvent e) {
Document doc = e.getDocument();
int length = doc.getLength();
try {
String text = doc.getText(0, length);
myModel.setLabelText(text);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
});
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(tabbedPane, BorderLayout.CENTER);
add(new MyPanel(myModel), BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
SharedModels mainPanel = new SharedModels();
JFrame frame = new JFrame("SharedModels");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MyModel {
private Document document = new PlainDocument();
private String labelText = "";
private EventListenerList eventListenerList = new EventListenerList();
private ChangeEvent changeEvent = null;
public void addChangeListener(ChangeListener l) {
eventListenerList.add(ChangeListener.class, l);
}
public void removeChangeListener(ChangeListener l) {
eventListenerList.remove(ChangeListener.class, l);
}
public String getLabelText() {
return labelText;
}
public void setLabelText(String labelText) {
this.labelText = labelText;
fireChangeListeners();
}
protected void fireChangeListeners() {
Object[] listeners = eventListenerList.getListenerList();
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i] == ChangeListener.class) {
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
}
}
}
public Document getDocument() {
return document;
}
}
#SuppressWarnings("serial")
class MyPanel extends JPanel {
private JLabel label = new JLabel("");
private JTextField textField = new JTextField(10);
public MyPanel(MyModel myModel) {
textField.setDocument(myModel.getDocument());
myModel.addChangeListener(ce -> {
label.setText(myModel.getLabelText());
});
add(new JLabel("Label text:"));
add(label);
add(textField);
setPreferredSize(new Dimension(400, 100));
}
}

How to solve the error? swing button repaint

I am using the menu to try to change the button number.
But this should not refresh.
How do I solve this?
I want 'file -> modify -> button 10x10 -> 20x20 change. '
To test and modify the source below. Please...
Please give me change the source. TT
package com.test;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MineMain extends JFrame {
private GridLayout grid;
private JPanel jp;
private int rownum, colnum;
private JButton[][] btn = null;
public MineMain(){
super("MINE");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Menu_Init();
// grid = new GridLayout();
// jp = new JPanel();
rownum = 10;
colnum = 10;
Init(200, 250);
}
private void setBtn(int row, int col){
btn = new JButton[row][col];
}
public void Init(int w, int h){
if(jp != null)
jp.removeAll();
else
jp = null;
btn = null;
jp = null;
// jp.removeAll();
grid = new GridLayout(rownum, colnum, 0, 0);
jp = new JPanel(grid);
setBtn(rownum, colnum);
for(int i=0;i<btn.length;i++){
for(int j=0;j<btn[i].length;j++){
btn[i][j] = new JButton();
jp.add(btn[i][j]);
}
}
// jp.revalidate();
// jp.repaint();
this.add(jp);
this.setSize(w, h);
this.setLocation(200, 200);
this.setVisible(true);
this.setResizable(false);
}
public void Menu_Init(){
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
JMenu filemenu = new JMenu("File(F)");
filemenu.setMnemonic('F');
JMenuItem startmenu = new JMenuItem("New Game(N)");
startmenu.setMnemonic('N');
startmenu.setActionCommand("NEW START");
startmenu.addActionListener(new MenuActionListener());
filemenu.add(startmenu);
JMenuItem minecntmenu = new JMenuItem("MINE MODIFY(M)");
minecntmenu.setMnemonic('M');
minecntmenu.setActionCommand("MODIFY");
minecntmenu.addActionListener(new MenuActionListener());
filemenu.add(minecntmenu);
JMenuItem close = new JMenuItem("CLOSE(C)");
close.setMnemonic('C');
filemenu.add(close);
bar.add(filemenu); //JMenuBar에 JMenu 부착
}
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("START")){
JOptionPane.showMessageDialog(null, "NEW GAME", "MINE", JOptionPane.YES_NO_OPTION);
} else if(e.getActionCommand().equals("MODIFY")){
modify(2);
}
}
}
private void modify(int lvl){
rownum = 20;
colnum = 20;
Init(400, 500);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new MineMain();
}
}
I see you are calling Init() again on modify().
Within Init(), I am assuming you are using
if(jp != null)
jp.removeAll();
else
jp = null;
to clear out the JPanel?
You want to remove the existing JPanel (i.e. jp) from the JFrame (i.e. this) before continuing at this point.
So, you could change your code to
if(jp != null) {
// JPanel already exists. so, remove JPanel jp from the JFrame
this.remove(jp);
jp.removeAll();
} else
jp = null;

JScrollPane displays the content using only the horizontal scroll bar

I want to display a list of strings in a window and i tried to use a JPanel surounded by JScrollPane because the size of the strings list is unknown. The problem is that the window is displaying the text Horizontally and i want to be displayed line after line. How to fix this? This is the code i've written so far.
package interface_classes;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextArea;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
public class ErrorMessageW {
private JFrame errorMessageW;
private ArrayList<String> errors;
private JPanel panel;
private JScrollPane scrollPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
final ArrayList<String> err = new ArrayList<>();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ErrorMessageW window = new ErrorMessageW(err);
window.errorMessageW.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ErrorMessageW(ArrayList<String> err) {
errors = err;
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
errorMessageW = new JFrame();
errorMessageW.setTitle("Unfilled forms");
errorMessageW.setBounds(100, 100, 367, 300);
errorMessageW.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnOk = new JButton("OK");
btnOk.setBounds(239, 208, 89, 23);
btnOk.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
errorMessageW.dispose();
}
});
errorMessageW.getContentPane().setLayout(null);
errorMessageW.getContentPane().add(btnOk);
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(10, 10, 330, 175);
errorMessageW.getContentPane().add(scrollPane);
panel = new JPanel();
for(String s : errors){
JTextArea text = new JTextArea(1,20);
text.setText(s);
text.setFont(new Font("Verdana",1,10));
text.setForeground(Color.RED);
panel.add(text);
}
scrollPane.setViewportView(panel);
}
public JFrame getErrorMessageW() {
return errorMessageW;
}
public void setErrorMessageW(JFrame errorMessageW) {
this.errorMessageW = errorMessageW;
}
}
This is what i get
This is what i want, but using the JScrollPane:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.ArrayList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class ErrorMessageW {
private JFrame errorMessageW;
private ArrayList<String> errors;
private JPanel panel;
private JScrollPane scrollPane;
private JTextArea errorMessage = new JTextArea(3, 30);
/**
* Launch the application.
*/
public static void main(String[] args) {
final ArrayList<String> err = new ArrayList<String>();
err.add("Short String");
err.add("A very very very very very very very very very very very "
+ "very very very very very very very very very very very "
+ "very very very very very very very very long String");
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ErrorMessageW window = new ErrorMessageW(err);
window.errorMessageW.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ErrorMessageW(ArrayList<String> err) {
errors = err;
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
errorMessageW = new JFrame();
JPanel contentPane = new JPanel(new BorderLayout(5, 15));
contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
errorMessage.setLineWrap(true);
errorMessage.setWrapStyleWord(true);
JScrollPane jsp = new JScrollPane(
errorMessage,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
);
contentPane.add(jsp, BorderLayout.PAGE_START);
errorMessageW.add(contentPane);
errorMessageW.setTitle("Unfilled forms");
errorMessageW.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JButton btnOk = new JButton("OK");
btnOk.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
errorMessageW.dispose();
}
});
JPanel btnConstrain = new JPanel(new FlowLayout(FlowLayout.TRAILING));
btnConstrain.add(btnOk);
contentPane.add(btnConstrain, BorderLayout.PAGE_END);
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
contentPane.add(scrollPane, BorderLayout.CENTER);
DefaultListModel<String> listModel = new DefaultListModel<String>();
for (String s : errors) {
listModel.addElement(s);
}
final JList<String> errorList = new JList<String>(listModel);
Dimension preferredSize = new Dimension(errorMessage.getPreferredSize().width,200);
errorList.setPreferredSize(preferredSize);
ListSelectionListener errorSelect = new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
errorMessage.setText(errorList.getSelectedValue());
}
};
errorList.addListSelectionListener(errorSelect);
scrollPane.setViewportView(errorList);
errorMessageW.pack();
}
public JFrame getErrorMessageW() {
return errorMessageW;
}
public void setErrorMessageW(JFrame errorMessageW) {
this.errorMessageW = errorMessageW;
}
}
First of all, you could try, instead of creating multiple instances of JTextArea, using only one and appending each error to it like this:
JTextArea text = new JTextArea(1, 20);
text.setFont(new Font("Verdana",1,10));
text.setForeground(Color.RED);
for(String s : errors) {
text.append(s + "\n");
}
panel.add(text);
However, if you do need to create more than one JTextArea, you can use a BoxLayout like this:
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
You just need to write a function that adds a new line character as an element of your ArrayList after every other element in your ArrayList of errors. Below i did a test program that shows how that can be done. I also checked the oputput. Just paste the code and understand the working of code. All the best!
import java.util.ArrayList;
public class TestingArraylist {
static ArrayList<String> errors = new ArrayList<String>();
static final String[] warnings = new String[]{"Error 0 occured","Error 1 occured","Error 2 occured","Error 3 occured","Error 4 occured"};;
public static void addNewLineToArrayList(String[] elementofarraylist){
for(int i =0;i<elementofarraylist.length;i++){
errors.add(elementofarraylist[i]);
errors.add("\n"); //this is what you need to do!
}
}
public static void main(String[] args) {
addNewLineToArrayList(warnings);
//checking below if our work has really succeded or not!!
for(int j =0;j<errors.size();j++){
System.out.print(errors.get(j));
}
}
}

Arrow Keys Not Working in Custom Search Component

I am developing a custom search component. When clicked on the button(search image icon) inside the text field, a table is displayed. The code is in very nascent stage so lots of things is not there.
As of now, I am stuck because I am not able to navigate the table with the arrow keys. Neither am I able to move to the next text field with "tab" key, once I select a row in the table.
The objective of the component is to select a row from the table and then with the help of the supporting methods(yet to be written) values from other labels and text fields would be defaulted while defaulting 1 st column value in the text field it is attached to.
Would really appreciate your help. Thanks !!
package myTableCombo;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class SearchBox extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField editor;
private JButton arrowButton;
private JWindow jWindow;
private Component userComponent;
public SearchBox() {
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
editor = new JTextField();
editor.setPreferredSize(new Dimension(250, 25));
initialize();
addListeners();
setBorders();
}
private void addListeners() {
arrowButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showWindow();
}
});
}
protected void showWindow() {
if (null != getWindowComponent()) {
jWindow = new JWindow();
jWindow.getContentPane().add(getWindowComponent());
jWindow.setLocation(new Point(SearchBox.this.getLocationOnScreen().x, SearchBox.this.getLocationOnScreen().y + 25));
jWindow.pack();
jWindow.setVisible(true);
}
}
private Component getWindowComponent() {
return userComponent;
}
public void setWindowComponent(Component component) {
userComponent = component;
}
private void initialize() {
arrowButton = new BasicArrowButton(SwingConstants.SOUTH);//In my code there is an icon here
arrowButton.setBorder(null);
arrowButton.setContentAreaFilled(false);
}
private void setBorders() {
add(editor);
add(arrowButton);
setBackground(editor.getBackground());
setBorder(editor.getBorder());
editor.setBorder(null);
}
public JTextField getTextComponent() {
return editor;
}
public JButton getActionButton() {
return arrowButton;
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
protected static void createAndShowGUI() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setPreferredSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
panel.add(new JLabel("Test Table Combo"));
SearchBox searchBox = new SearchBox();
searchBox.userComponent = searchBox.new SearchBoxTable();
panel.add(searchBox);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class SearchBoxTable extends JScrollPane implements DocumentListener {
private static final long serialVersionUID = 1L;
private JTable table;
private Object[] columnNames;
private DefaultTableModel tableModel;
private Object[][] sheetDataInString;
private TableRowSorter<DefaultTableModel> rowSorter;
public SearchBoxTable() {
columnNames = new Object[]{"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"};
sheetDataInString = new Object[21][6];
for(int i =0; i < sheetDataInString.length; i++) {
for(int j = 0; j< 6; j++) {
sheetDataInString[i][j] = "Row Value : " + i + ", Column Value : " + j;
}
}
tableModel = new DefaultTableModel(sheetDataInString, columnNames) {
private static final long serialVersionUID = 1L;
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
rowSorter = new TableRowSorter<DefaultTableModel>(tableModel);
table = new JTable(tableModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setAutoCreateRowSorter(true);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font(null, Font.PLAIN, 13));
setPreferredSize(new Dimension(500, 225));
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
getViewport().add(table);
}
#Override
public void changedUpdate(DocumentEvent e) {
newFilter(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
newFilter(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
newFilter(e);
}
/**
* Update the row filter regular expression from the expression/string/data in the text box.
*
* #param documentEvent
*/
private void newFilter(DocumentEvent documentEvent) {
RowFilter<DefaultTableModel, Object> rowFilter = null;
Document document = documentEvent.getDocument();
String filterText;
try {
filterText = document.getText(0, document.getLength()).trim();
rowFilter = RowFilter.regexFilter("(?i)" + filterText);
} catch (java.util.regex.PatternSyntaxException e) {
return;
} catch (BadLocationException badLocationException) {
return;
}
rowSorter.setRowFilter(rowFilter);
table.setRowSorter(rowSorter);
}
}
}
do you meaning
use undecorated JDialog instead of JWindow, otherwise JTextComponets aren't editable
JDialog has better support for AlwaysOnTop and ModalityTypes (only hardcoded to the setAlwaysOnTop)
don't to recreate basic setting again and again, don't to recreate a popup windod, use lolac variable, remove all contents and add a new ony, define all setting for JDialog once time, see exception (The dialog is displayable.) in the case that popup is hidden and value in JTextField isn't empty
missed action for hide JDialog on ESC key event, hide JDialog, if is JFrame minimalized
missed moving with JDialog if JFrame is resized, moved over screen on another Point,
attach Document to the JTextField directly, not lost somwhere in to the JScrollPane definitions
your code missing a few good practicies, then everything is possible but not with this code (after my edit too)
search for JCalendar by Kay Toedter (best popup workaround as I saw for popup window)
only removed uselles methods, moved from- to, notice non_optimized_code, simple put to the recyclebin and wrote that again
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class SearchBox extends JPanel {
private static final long serialVersionUID = 1L;
private static JFrame frame = new JFrame();
private JTextField editor;
private JButton arrowButton;
//private JToggleButton arrowButton;
private JDialog popupWindow = new JDialog(frame);
private Component userComponent;
private JTable table;
private TableRowSorter<DefaultTableModel> rowSorter;
private Object[] columnNames;
private DefaultTableModel tableModel;
private Object[][] sheetDataInString;
public SearchBox() {
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
editor = new JTextField();
editor.setPreferredSize(new Dimension(250, 25));
editor.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void changedUpdate(DocumentEvent e) {
newFilter();
}
#Override
public void insertUpdate(DocumentEvent e) {
newFilter();
}
#Override
public void removeUpdate(DocumentEvent e) {
newFilter();
}
private void newFilter() {
RowFilter<DefaultTableModel, Object> rowFilter = null;
Document document = editor.getDocument();
String filterText;
try {
filterText = document.getText(0, document.getLength()).trim();
rowFilter = RowFilter.regexFilter("(?i)" + filterText);
} catch (java.util.regex.PatternSyntaxException e) {
return;
} catch (BadLocationException badLocationException) {
return;
}
rowSorter.setRowFilter(rowFilter);
table.setRowSorter(rowSorter);
}
});
initialize();
addListeners();
setBorders();
}
private void addListeners() {
arrowButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (!popupWindow.isVisible()) {
showWindow();
} else {
hideWindow();
}
}
});
}
protected void showWindow() {
if (null != getWindowComponent()) {
popupWindow.getContentPane().add(getWindowComponent());
popupWindow.setLocation(new Point(SearchBox.this.getLocationOnScreen().x, SearchBox.this.getLocationOnScreen().y + 25));
popupWindow.setUndecorated(true);
popupWindow.setAlwaysOnTop(true);
popupWindow.pack();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
popupWindow.setVisible(true);
}
});
}
}
protected void hideWindow() {
popupWindow.setVisible(false);
}
private Component getWindowComponent() {
return userComponent;
}
public void setWindowComponent(Component component) {
userComponent = component;
}
private void initialize() {
arrowButton = new BasicArrowButton(SwingConstants.SOUTH);//In my code there is an icon here
arrowButton.setBorder(null);
arrowButton.setContentAreaFilled(false);
}
private void setBorders() {
add(editor);
add(arrowButton);
setBackground(editor.getBackground());
setBorder(editor.getBorder());
editor.setBorder(null);
}
public JTextField getTextComponent() {
return editor;
}
public JButton getActionButton() {
return arrowButton;
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
protected static void createAndShowGUI() {
JPanel panel = new JPanel();
frame.setPreferredSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
panel.add(new JLabel("Test Table Combo"));
SearchBox searchBox = new SearchBox();
searchBox.userComponent = searchBox.new SearchBoxTable();
panel.add(searchBox);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class SearchBoxTable extends JScrollPane {
private static final long serialVersionUID = 1L;
public SearchBoxTable() {
columnNames = new Object[]{"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"};
sheetDataInString = new Object[21][6];
for (int i = 0; i < sheetDataInString.length; i++) {
for (int j = 0; j < 6; j++) {
sheetDataInString[i][j] = "Row Value : " + i + ", Column Value : " + j;
}
}
tableModel = new DefaultTableModel(sheetDataInString, columnNames) {
private static final long serialVersionUID = 1L;
#Override
public boolean isCellEditable(int row, int column) {
return true;
}
};
rowSorter = new TableRowSorter<DefaultTableModel>(tableModel);
table = new JTable(tableModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setAutoCreateRowSorter(true);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font(null, Font.PLAIN, 13));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
getViewport().add(table);
}
}
}

Undo and redo methods for awt `Graphics` objects

I' making this simple paintbrush-type paint toolbox (some interesting ideas in my previous question)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class MainClass2{
static JLabel colorlabel = new JLabel(" Color ");
public static JLabel xlab = new JLabel("0");
public static JLabel ylab = new JLabel("0");
static JFrame frame1 = new JFrame();
static JButton quitbutton = new JButton("Quit");
static JButton infobutton = new JButton("Info");
static JButton clearbutton = new JButton("Clear");
static JButton savebutton = new JButton("Save");
private static int stroke1 = 4;
static SpinnerNumberModel spinnervals = new SpinnerNumberModel(stroke1,1,15,1);
static JSpinner spinnerbrush = new JSpinner(spinnervals);
static JButton selectcolor = new JButton("Select Color");
static JButton selectbg = new JButton("Select Background");
public static Color col1 = Color.WHITE;
private static Color col2 = Color.WHITE;
static AuxClass4 panel1 = new AuxClass4(col1, col2, stroke1);
static JPanel panel2 = new JPanel();
static JPanel panel3 = new JPanel();
static JPanel panel4 = new JPanel();
private static void addPanel1(){
panel1.setPreferredSize(new Dimension(800,500));
}
private static void addPanel2(){
ButtonAction inst1 = new ButtonAction();
xlab.setMinimumSize(new Dimension(30,30));
ylab.setMinimumSize(new Dimension(30,30));
xlab.setBorder(BorderFactory.createLineBorder(Color.BLACK));
ylab.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel2.add(new JLabel(" X: "));
panel2.add(xlab);
panel2.add(new JLabel(" Y: "));
panel2.add(ylab);
panel2.add(savebutton);
panel2.add(clearbutton);
panel2.add(quitbutton);
panel2.add(infobutton);
panel2.setLayout(new FlowLayout());
quitbutton.addActionListener(inst1);
infobutton.addActionListener(inst1);
clearbutton.addActionListener(inst1);
savebutton.addActionListener(inst1);
selectcolor.addActionListener(inst1);
selectbg.addActionListener(inst1);
}
//add to panel3
private static void addPanel3(){
StrokeAction inst2 = new StrokeAction();
spinnerbrush.addChangeListener(inst2);
panel3.add(new JLabel("Stroke size"));
panel3.add(spinnerbrush);
panel3.add(selectcolor);
panel3.add(new JLabel("Current color:"));
colorlabel.setSize(20, 20);
colorlabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
colorlabel.setOpaque(true);
colorlabel.setBackground(Color.WHITE);
colorlabel.setForeground(Color.WHITE);
panel3.add(colorlabel);
panel3.add(selectbg);
}
private static class ButtonAction implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource()==quitbutton){
System.exit(0);
}
else if(arg0.getSource()==infobutton){
JOptionPane.showMessageDialog(frame1, "Paint Toolbox designed in Java");
}
else if(arg0.getSource()==selectcolor){
panel1.changeColor();
}
else if(arg0.getSource()==selectbg){
panel1.changeBg();
}
else if(arg0.getSource()==clearbutton){
panel1.colfg = panel1.colbg;
colorlabel.setBackground(panel1.colfg);
colorlabel.setForeground(panel1.colfg);
panel1.setForeground(null);
}
else if(arg0.getSource()==savebutton){
panel1.saveImage();
}
}
}
private static class StrokeAction implements ChangeListener{
#Override
public void stateChanged(ChangeEvent arg0) {
if (arg0.getSource()==spinnerbrush){
Object o1 = spinnervals.getValue();
Integer int1 = (Integer) o1;
stroke1 = int1.intValue();
panel1.changeStroke(stroke1);
}
// TODO Auto-generated method stub
}
}
public static void main(String args[]){
addPanel1();
addPanel2();
addPanel3();
frame1.add(panel1, BorderLayout.NORTH);
frame1.add(panel2, BorderLayout.SOUTH);
frame1.add(panel3, BorderLayout.CENTER);
frame1.setTitle("PaintBox v2.2");
frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame1.setSize(800,600);
frame1.setResizable(false);
frame1.setLocationRelativeTo(null);
frame1.setVisible(true);
}
}
class AuxClass4 extends JPanel implements MouseMotionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
private int xval;
private int yval;
public Color colfg;
public Color colbg;
public int strokesize;
public int fileorder;
public AuxClass4(Color input1, Color input2, int input3){
colfg=input1;
colbg=input2;
strokesize = input3;
this.setBorder(BorderFactory.createLineBorder(Color.CYAN, 10));
this.setBackground(colbg);
//this.setMaximumSize(new Dimension(500,380));
this.addMouseMotionListener(this);
}
public void paintComponent(Graphics g1){
super.paintComponent(g1);
g1.setColor(colfg);
g1.fillRect(xval, yval, strokesize, strokesize);
}
#Override
public void mouseDragged(MouseEvent arg0) {
xval = arg0.getX();
yval = arg0.getY();
repaint(xval, yval, strokesize,strokesize);
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent arg0) {
xval = arg0.getX();
yval = arg0.getY();
String xvalret = Integer.toString(xval);
String yvalret = Integer.toString(yval);
MainClass2.xlab.setText(" " + xvalret + " ");
MainClass2.ylab.setText(" " + yvalret + " ");
}
public void changeColor(){
colfg = JColorChooser.showDialog(this, "Select color", colfg);
MainClass2.colorlabel.setBackground(colfg);
MainClass2.colorlabel.setForeground(colfg);
}
public void changeBg(){
colbg=JColorChooser.showDialog(this, "Select color", Color.WHITE);
colfg=colbg;
this.setBackground(colbg);
MainClass1.colorlabel.setBackground(colfg);
MainClass1.colorlabel.setForeground(colfg);
}
public void changeStroke(int inputstroke){
strokesize=inputstroke;
}
public void saveImage(){
final String dir = System.getProperty("user.dir");
JOptionPane.showMessageDialog(this, "File saved under " + dir + "/saveimage" + fileorder +".png");
fileorder+=1;
}
}
It works fine for now, but I started wondering if it is possible to implement undo and redo methods for Graphics objects. Intuitively, there should be some way to add the created objects to some table in a 'historical' order. User then should be able to navigate in this table.
Unfortunately, I have no experience with this approach, especially with graphics, so any suggestion would be massively welcome.
I would recommend UndoManager
http://docs.oracle.com/javase/6/docs/api/javax/swing/undo/UndoManager.html
See also the example
http://www.java2s.com/Code/Java/Swing-JFC/Undomanager.htm
Take a look at the command pattern. I think this javaworld article explains it quite nicely.
In a nutshell you will have to have an interface containing undo and redo. Objects that implement this will be added to a list. As you undo and redo you can navigate through the list calling undo and redo. It means that you may have to write more code becuase for every event you actually draw you will have to write the equivelent to undo it.

Categories

Resources