I want to use JavaBeans Persistence mechanism to save my GUI to local disk. The problem that I faced is to save two frames at one time. Here is my code.
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import javax.swing.*;
public class BeansTest {
private static JFileChooser chooser;
private JFrame frame;
public static void main(String[] args){
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
BeansTest test = new BeansTest();
test.init();
}
public void init(){
frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("PersistentFrameTest");
frame.setSize(400,200);
JButton registryButton = new JButton("Registry");
frame.add(registryButton);
registryButton.addActionListener(EventHandler.create(ActionListener.class, this, "registry"));
JButton saveButton = new JButton("Save");
frame.add(saveButton);
saveButton.addActionListener(EventHandler.create(ActionListener.class, this, "save"));
frame.setVisible(true);
}
public void registry(){
Registry re = new Registry();
}
public void save()
{
if(chooser.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
{
try{
File file = chooser.getSelectedFile();
XMLEncoder encoder = new XMLEncoder(new FileOutputStream(file));
encoder.writeObject(frame);
encoder.close();
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null, e);
}
}
}
}
public class Registry {
public Registry(){
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.setSize(400,200);
JLabel nameL = new JLabel("Name:");
JTextField nameF = new JTextField(8);
frame.add(nameL);
frame.add(nameF);
frame.setVisible(true);
}
}
I want to save two frames at the same when I press the saveButton. Now I can only save the main frame. Please help me solve this problem. Many Thanks.
As the JFrame in the Registry class is not accessible you will need to add a getter to this class. Then, given that the Registry creation is dependent on an ActionListener, you will need to check that your Registry handle re has been instantiated before saving that frame. In code:
Add to Registry:
public JFrame getFrame() {
return frame;
}
Add to BeansTest.save():
if (re.getFrame() != null) {
encoder.writeObject(re.getFrame());
}
Some variables here will need to be moved to global scope. I think that you will benefit from figuring out these bits yourself.
Related
I am quite new to Java and learning as a student. I hope you can understand me.
As you can see from the code below, I've only coded the frame and the label. The user should be able to write some song recommendations. There should be at least a few text fields created by an array. When the user makes changes, the new text should be displayed using JOptionPane.WARNING_MESSAGE.
I need some guidance on how I can create an array of JTextField and retrieve the text from an array of String. In addition, how can I use JOptionPane to display all of the text?
Thank you.
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
class TextFrame extends JFrame
{
private final JLabel cLabel;
public TextFrame()
{
super("Hello there!");
setLayout(new FlowLayout());
cLabel = new JLabel("Please write some song recommendations.");
cLabel.setToolTipText("Write below.");
add(cLabel);
}
}
public class TestFrame
{
public static void main (String [] args)
{
TextFrame frame = new TextFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 400);
frame.setVisible(true);
}
}
You should make an actionListener that checks to see if you have typed anything. You could have another listener or Mnemonic so when you hit enter it will update everything. When you hit enter, you could get the text from the JTextField or JTextArea and then save that into an array of Strings (ie String[] stringArray = new String[<num of items>] This way you could just have one textField and you will be able to store everything in a String[] instead of an array of Text Fields? I hope this helps!
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class framearray2 extends JFrame implements ActionListener
{
JCheckBox c1[];
JTextField t1[];
int i;
framearray2(String p)
{
super(p);
c1=new JCheckBox[2];
t1=new JTextField[2];
for(i=0;i<2;i++)
{
t1[i]=new JTextField(40);
c1[0]=new JCheckBox("Singing");
c1[0].setBackground(Color.red);
c1[1]=new JCheckBox("Cricket",true);
}
for(i=0;i<2;i++)
{
add(t1[i]);
add(c1[i]);
t1[i].addActionListener(this);
}
setLayout(new FlowLayout());
setFont(new Font("Arial",Font.ITALIC,40));
}
public void actionPerformed(ActionEvent e)
{
for(i=0;i<2;i++)
{
if(e.getSource().equals(t1[0]))
{
t1[0].setBackground(Color.red);
}
if(e.getSource().equals(t1[1]))
{
t1[1].setBackground(Color.blue);
}
}
}
public static void main(String s[])
{
framearray2 f1=new framearray2("hello");
f1.setSize(600,500);
f1.setVisible(true);
}
}
The following example creates a JFrame with JButton, JTextField and JLabel.
When the button is pressed it increments the value in the text field and label.
This example also creates a 2nd JFrame that is a copy of the first.
The button, text field and label is copied as well.
The issue at hand is the button on the copied frame still updates the text field and label on the original. The 'why' is fairly obvious and is because the code makes specific reference to the text field and label.
Although this isn't written in the best manner but it is a great example of the scenario in which I am addressing.
The objective is, without a major rewrite, what would be the least invasive way to have the copied button action update the copied test field and label instead of the original?
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.JTextField;
class ButtonTextFieldLabel extends JFrame
{
JButton bnt1 = new JButton("B1");
JTextField tf1 = new JTextField("1");
JLabel lbl1 = new JLabel("100");
public ButtonTextFieldLabel()
{
super("Main Frame");
setLayout(null);
bnt1.setBounds(50,100,120,40);
tf1.setBounds(300,100, 80,40);
lbl1.setBounds(200,100,80,40);
bnt1.addActionListener(new ListenerHolder(this));
add(bnt1);
add(tf1);
add(lbl1);
setSize(500,500);
makeCopy(this);
setVisible(true);
}
private void makeCopy(ButtonTextFieldLabel originalObj)
{
JFrame copyFrame = new JFrame();
copyFrame.setTitle("Copy of " + originalObj.getTitle());
copyFrame.setSize(originalObj.getSize());
copyFrame.setLocation(originalObj.getX()+100, originalObj.getY()+100);
copyFrame.setLayout(null);
JButton copyBnt1 = new JButton();
copyBnt1.setBounds(originalObj.bnt1.getBounds());
copyBnt1.setLabel(originalObj.bnt1.getLabel());
copyFrame.add(copyBnt1);
for (ActionListener al : originalObj.bnt1.getActionListeners())
{
copyBnt1.addActionListener(al);
}
JTextField copyTf1 = new JTextField();
copyTf1.setBounds(originalObj.tf1.getBounds());
copyTf1.setText(originalObj.tf1.getText());
JLabel copyLbl1 = new JLabel();
copyLbl1.setBounds(originalObj.lbl1.getBounds());
copyLbl1.setText(originalObj.lbl1.getText());
copyFrame.add(copyBnt1);
copyFrame.add(copyTf1);
copyFrame.add(copyLbl1);
copyFrame.setVisible(true);
}
public void runThis()
{
tf1.setText( Integer.toString(Integer.parseInt(tf1.getText())+1) );
lbl1.setText( Integer.toString(Integer.parseInt(lbl1.getText())+1) );
}
}
class ListenerHolder implements ActionListener
{
ButtonTextFieldLabel ph;
public ListenerHolder(ButtonTextFieldLabel ph)
{
this.ph = ph;
}
#Override
public void actionPerformed(ActionEvent arg0)
{
ph.runThis();
}
}
public class TestBTL
{
public static void main(String[] args){
new ButtonTextFieldLabel();
}
}
You already know the reason for the problem -- you're copying the original ActionListener, complete with its reference to the original GUI components. The overall solution is not to copy the action listener but rather to create your GUI's to hold and maintain their own unique state. One solution is rather than try to copy components via kludge, to create a self-contained GUI object that holds and updates its own state. You can create multiple GUI's using a factory method if desired.
For example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class TestBtl2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndDisplayFrame("Frame 1").setVisible(true);
createAndDisplayFrame("Frame 2").setVisible(true);
});
}
// Factory method
private static JFrame createAndDisplayFrame(String text) {
BtlPanel btlPanel = new BtlPanel();
JFrame frame = new JFrame(text);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(btlPanel);
frame.pack();
frame.setLocationByPlatform(true);
return frame;
}
}
class BtlPanel extends JPanel {
private int value = 0;
private JButton button1 = new JButton(new ButtonAction("Button 1"));
private JLabel label1 = new JLabel("00");
private JTextField textField1 = new JTextField("00");
public BtlPanel() {
textField1.setFocusable(false);
add(button1);
add(Box.createHorizontalStrut(20));
add(label1);
add(Box.createHorizontalStrut(20));
add(textField1);
setPreferredSize(new Dimension(300, 100));
}
public void incrementValue() {
value++;
String text = String.format("%02d", value);
label1.setText(text);
textField1.setText(text);
}
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
incrementValue();
}
}
}
Side Recommendations:
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Check out: The Use of Multiple JFrames, Good/Bad Practice?
I have an object ReminderGUI which has a JTextArea field. ReminderGUI represents an app which lets save and display reminders. When getReminderButton is clicked I want the app to find the reminder which was previously saved for this date and display it in the JTextArea (I'm not showing this functionality in the code snippet).
I'm having trouble with changing JTextArea text and the code below demonstrates it. Once getReminderButton is clicked then getReminderButtonHandler() is supposed to initialize a new blank JTextArea and then append it to some new text here. Why doesn't this work?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ReminderGUI extends JFrame implements ActionListener{
private JButton getReminderButton;
private JTextArea reminderTextArea;
public ReminderGUI() {
super();
super.setLayout(new BorderLayout());
this.reminderTextArea = new JTextArea("Enter text");
this.getReminderButton = new JButton("Get reminder");
JPanel southPanel = new JPanel();
southPanel.add(getReminderButton, BorderLayout.SOUTH);
super.add(southPanel, BorderLayout.SOUTH);
super.add(reminderTextArea, BorderLayout.CENTER);
this.getReminderButton.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == this.getReminderButton) {
this.getReminderButtonHandler();
}
}
private void getReminderButtonHandler() {
this.reminderTextArea = new JTextArea("");
this.reminderTextArea.append("some new text here");
}
public static void main(String[] args) {
ReminderGUI rmg = new ReminderGUI();
rmg.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rmg.setSize(500, 300);
rmg.setVisible(true);
}
}
The problem is in this line: this.reminderTextArea = new JTextArea("Enter text"); you're creating a new TextArea
You can set it using the set method, like this: reminderTextArea.setText(text);
I have just started working on a small GUI for an assignment, but upon launching it, nothing apart from the title is visible.
My code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Property extends JFrame
{
/*private String propertyType;
private String propertyAddress;
private double propertyArea;
private int numOfBedrooms;
private int numOfGarages;
private int numOfToilets;
private String ownerGivenName;
private String ownerSurname;
private String ownerdateOfBirth;*/
JButton PropertySaleButton = new JButton("Add New Property");
JButton PurchaseOfferButton = new JButton("Submit Purchase Offer");
public Property()
{
setLayout (new FlowLayout());
add(PropertySaleButton);
add(PurchaseOfferButton);
}
public static void main(String[] args)
{
EventQueue.invokeLater(() ->
{
JFrame frame = new JFrame("CQ Real Estate");
/*Image img = new ImageIcon("icon.gif").getImage();
setIconImage(img);*/
frame.setSize(450, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
If anyone can tell me what I'm missing it would be greatly appreciated.
Property is the class that hold your "GUI design" but didn't use it. You build a JFrame. Instead, create a Property instace
JFrame frame = new Property();
You will need to adapt a bit your code (to add the title).
Try changing your code to:
this.getContentPane.add(PropertySaleButton);
this.getContentPane.add(PurchaseOfferButton);
Just started out using Java and am a beginner. I tried to create a photo viewer which can search a directory for an image and open the image but my program won't display the image.
When i run the program, it opens up and shows a menubar which i use to search my directories, but even if i select an image it won't display. TIA.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.imageio.ImageIO;
public class ICS
{
private JPanel gui;
private JFileChooser fileChooser;
FilenameFilter fileNameFilter;
private JMenuBar menuBar;
DefaultListModel model;
public ICS() {
gui = new JPanel(new GridLayout());
final JLabel imageView = new JLabel();
gui.add(imageView);
fileChooser = new JFileChooser();
String[] imageTypes = ImageIO.getReaderFileSuffixes();
menuBar = new JMenuBar();
JMenu menu = new JMenu("GET PHOTO HERE");
menuBar.add(menu);
JMenuItem browse = new JMenuItem("browse");
menu.add(browse);
browse.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int result = fileChooser.showOpenDialog(gui);
if (result==JFileChooser.APPROVE_OPTION) {
File eg = fileChooser.getSelectedFile();
}
}
});
}
public void loadImages(File directory) throws IOException {
File[] imageFiles = directory.listFiles(fileNameFilter);
BufferedImage[] images = new BufferedImage[imageFiles.length];
}
public Container getGui() {
return gui;
}
public JMenuBar getMenuBar() {
return menuBar;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
ICS imageList = new ICS();
JFrame f = new JFrame("Image Browser");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.add(imageList.getGui());
f.setJMenuBar(imageList.getMenuBar());
f.setLocationByPlatform(true);
f.pack();
f.setSize(800,600);
f.setVisible(true);
}
});
}
}
You're not doing anything with your selected file. Given that you have an empty JLabel in your JPanel, you could simply set the Icon for that component:
imageView.setIcon(new ImageIcon(eg.getPath()));
It's not doing anything with the image because you've never told it to. In your action listener, you've created a file chooser and gotten the selected file, but you never do anything with it. You just define it as a local variable inside the action listener, which is then immediately destroyed when your listener exits.
What you should be doing is, inside of your action listener, make a function call that actually displays your image after you retrieve the file the user selected.
Also, ICS is a terrible name for a class. You should be descriptive of your class names for your own reference and sanity when your program gets larger and you're trying to remember what everything did.