I have managed to serialize my very basic GUI-object containing a JTextArea and a few buttons to a file 'test.ser'.
Now, I would like to completely restore the previously saved state from 'test.ser', but seem to have a misconception of how to properly deserialize an objects state.
The class MyFrame creates the JFrame and serializes it.
public class MyFrame extends JFrame implements ActionListener {
// Fields
JTextArea textArea;
String title;
static MyFrame gui = new MyFrame();
private static final long serialVersionUID = 1125762532137824262L;
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
gui.run();
}
// parameterless default contructor
public MyFrame() {
}
// constructor with title
public MyFrame(String title) {
}
// creates Frame and its Layout
public void run() {
JFrame frame = new JFrame(title);
JPanel panel_01 = new JPanel();
JPanel panel_02 = new JPanel();
JTextArea textArea = new JTextArea(20, 22);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
panel_01.add(scrollPane);
// Buttons
JButton saveButton = new JButton("Save");
saveButton.addActionListener(this);
JButton loadButton = new JButton("Load");
loadButton.addActionListener(this);
panel_02.add(loadButton);
panel_02.add(saveButton);
// Layout
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(BorderLayout.CENTER, panel_01);
frame.getContentPane().add(BorderLayout.SOUTH, panel_02);
frame.setSize(300, 400);
frame.setVisible(true);
}
/*
*
*/
public void serialize() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.ser"));
oos.writeObject(gui);
oos.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent ev) {
System.out.println("Action received!");
gui.serialize();
}
}
Here I try to do the deserialization:
public class Deserialize {
static Deserialize ds;
static MyFrame frame;
public static void main(String[] args) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.ser"));
frame = (MyFrame) ois.readObject();
ois.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Maybe somebody could point me into the direction where my misconception is?
How would you guys write a class, which deserializes and restores the previously serialized gui-elements to their previously serialized state?
The way I am doing it right now seems to have more than one flaw in its concept, right?
What happens? Are you getting an exception? From the looks of the code ds is never initialised. I believe, once deserialised, you will need to show the frame with frame.setVisible(true);. As always, Swing (and in fact AWT) should be used only on the AWT Event Dispatch Thread (EDT) - use java.awt.EventQueue.invokeLater.
Generally using statics is not a good idea. Nor is serialising GUI components. final is good, and will, for the most part, make sure instance and static fields are initialised.
As says in every javadoc swing component, the preferred way to serialize JFrame, and others JFoo is the XMLEncoder.
The classic serialization works in some little GUI applications, but not with long life GUI components applications.
Related
I know this gets asked alot but I can't find a solution to my problem. I assume my arguments are wrong in some way.
public class ImageFileHandler extends FileHandler {
public void displayImage() {
//Displaying an image
JLabel picLabel = new JLabel(new ImageIcon(img));
JPanel jPanel = new JPanel();
jPanel.add(picLabel);
JFrame frame = new JFrame();
frame.setSize(new Dimension(img.getWidth(),
img.getHeight()));
frame.add(jPanel);
frame.setVisible(true);
}
}
I want to call this displayImage() method in the following class.
public class FileApplicationTester {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedImage img;
try {
img = ImageIO.read(new File("D:\\Documents\\University\\Year_3\\Advanced Programming\\Week3\\supplementary materials-20190206\\images.jpeg"));
} catch (IOException e) {
e.printStackTrace();
}
ImageFileHandler Display = new ImageFileHandler();
ImageFileHandler.displayImage();
}
}
I'm getting an error with ImageFileHandler.displayImage();Tells me that the displayImage method needs to be static, but I don't want it to be static to that class right?
your created instance of ImageFileHandler is called Display
So use it like this instead : Display.displayImage();
Hello did you tried to do
Display.displayImage();
I am an absolute beginner in coding. I would like to know why is my Jframe blank when run, how do I fix it. From what I have research on the internet it seems that I should put the component inside the JFrame as it is empty but how do I do it
My Code
public class Video extends JFrame
{
public static void main(String[] args) throws URISyntaxException {
final URI uri = new URI("https://www.youtube.com/watch?v=rl0YiZjTqpw");
class OpenUrlAction implements ActionListener
{
#Override public void actionPerformed(ActionEvent e) {
open(uri);
}
}
JFrame frame = new JFrame("Links");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(410, 400);
Container container = frame.getContentPane();
container.setLayout(new GridBagLayout());
JButton btnclickHereTo = new JButton();
btnclickHereTo.setText("<HTML> <FONT color=\"#000099\"><U>Click Here To Watch Video</U></FONT>");
btnclickHereTo.setHorizontalAlignment(SwingConstants.LEFT);
btnclickHereTo.setBorderPainted(false);
btnclickHereTo.setOpaque(false);
btnclickHereTo.setBackground(Color.WHITE);
btnclickHereTo.setToolTipText(uri.toString());
btnclickHereTo.addActionListener(new OpenUrlAction());
container.add(btnclickHereTo);
frame.setVisible(true);
}
private static void open(URI uri)
{
if (Desktop.isDesktopSupported())
{
try
{
Desktop.getDesktop().browse(uri);
}
catch (IOException e)
{ /* TODO: error handling */ }
}
else
{ /* TODO: error handling */ }
}
}
public void setVisible(boolean b) {
Why would you override the setVisible(...) method of your frame? There is no reason to do that.
I am an absolute beginner in coding
Start with something basic, like the example from the Swing tutorial on How to Make Frames.
Keep a reference to the tutorial link handy since it contains information and examples for all Swing basics.
I want to update my look and feel by JRadioButtonMenuItem. And I searching in Stackoverflow but what I find was a big bunch of code in 1 class. For me as a beginner its easier to seperate function in a special class.
That is my Frame-Class.
public class CalenderFrame extends JFrame {
public CalenderFrame() throws HeadlessException {
createFrame();
}
public void createFrame() {
setJMenuBar(CalenderMenuBar.getInstance().createMenu());
setTitle("Calender");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(400, 300));
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
And that is my MenueBar Class. I just give a short one of Code that is specific for this question. This class is an Singleton.
public JMenuBar createMenu() {
JMenu lookAndFeelMenu = new JMenu("Look & Feel");
JRadioButtonMenuItem lAndFWindowsItem = new JRadioButtonMenuItem("Windows",true);
lAndFWindowsItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == lAndFWindowsItem) {
lAndFAction(1);
}
}
});
JRadioButtonMenuItem lAndFMetalItem = new JRadioButtonMenuItem("Metal",false);
lAndFMetalItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == lAndFMetalItem) {
lAndFAction(2);
}
}
});
JRadioButtonMenuItem lAndFMotifItem = new JRadioButtonMenuItem("Motif", false);
lAndFMotifItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == lAndFMotifItem) {
lAndFAction(3);
}
}
});
ButtonGroup group = new ButtonGroup();
group.add(lAndFWindowsItem);
group.add(lAndFMetalItem);
group.add(lAndFMotifItem);
lookAndFeelMenu.add(lAndFWindowsItem);
lookAndFeelMenu.add(lAndFMetalItem);
lookAndFeelMenu.add(lAndFMotifItem);
}
public void lAndFAction(int counter) {
try {
String plaf = "";
if (counter == 1) {
plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
} else if (counter == 2) {
plaf = "javax.swing.plaf.metal.MetalLookAndFeel";
} else if (counter == 3) {
plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
}
UIManager.setLookAndFeel(plaf);
//SwingUtilities.updateComponentTreeUI(this);
} catch (UnsupportedLookAndFeelException ue) {
System.err.println(ue.toString());
} catch (ClassNotFoundException ce) {
System.err.println(ce.toString());
} catch (InstantiationException ie) {
System.err.println(ie.toString());
} catch (IllegalAccessException iae) {
System.err.println(iae.toString());
}
}
}
I hope you guys can help me.
I'm not sure what your problem actually is. But, you must update your components after changing the LaF. According to the Look and Feel Documentation:
Changing the Look and Feel After Startup
You can change the L&F with setLookAndFeel even after the program's
GUI is visible. To make existing components reflect the new L&F,
invoke the SwingUtilities updateComponentTreeUI method once per
top-level container. Then you might wish to resize each top-level
container to reflect the new sizes of its contained components. For
example:
UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
Therefore, you would need a reference to the frame holding the components in your UI. An idea would be doing something like:
public class CalendarMenuBar {
// Add this field to tour factory
private static JFrame frameThatWillBeUpdated;
// ... (Your code goes here)
// update this method to receive the reference of the frame which will
// need to be refreshed (update the GUI)
public JMenuBar createMenu(JFrame frame) {
// sets the reference for the frame
frameThatWillBeUpdated = frame;
// ... (the rest of your code for this method)
}
// ...
// Update this method to refresh the frame
public void lAndFAction(int counter) {
try{
// ... (your code)
// Set the LaF
UIManager.setLookAndFeel(plaf);
// Update the component tree (frame and its children)
SwingUtilities.updateComponentTreeUI(frameThatWillBeUpdated);
// repack to resize
frame.pack();
} catch(Exception ex){
// Your catches
}
}
}
And here is how you use it when creating your frame (inside your CalenderFrame class):
public void createFrame() {
// use this frame as reference
setJMenuBar(CalenderMenuBar.getInstance().createMenu(this));
// ... (your code goes here)
}
Recently I have been getting into some Gui programming in Java. I noticed that when I created a JComboBox and tried to display in my gui that the text doesn't come in full. Alot of the time it is blurred, as shown as below. I have tried increasing the size of the GridBagConstraint but it still occurs. This would also happen to the button once I press it as well.
Class 1:
public class load {
private JFrame frame;
public static void main(String args[]) throws InvocationTargetException,
InterruptedException {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
// Create the UI here
load window = new load();
window.frame.setVisible(true);
}
});
}
private void loadGui() {
JButton create = new JButton();
create.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
SelectionView a = new SelectionView();
// VVPRIMARY ERROR CURRENTLY VV
// unable to setvisible false without the nextframe losing pixel
frame.setVisible(false);
frame.dispose();
}
});
frame.setSize(400, 400);
frame.add(create);
}
}
Class 2:
public class SelectionView extends JFrame {
public SelectionView() {
// intialize frame
JFrame selection = new JFrame("Sport Selection");
JPanel a = new JPanel();
a.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
selection.setSize(300, 500);
final JComboBox box = createDropdown();
JButton load = new JButton("Load");
load.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
int value = box.getSelectedIndex();
switch (value) {
case 0:
TableTennisView a = new TableTennisView();
break;
case 1:
BasketBallView b = new BasketBallView();
break;
default:
System.out.println("Nothing");
break;
}
}
});
// create comboBox
a.add(box, c);
a.add(load, c);
selection.add(a);
selection.setVisible(true);
}
/**
* Method CreateDropDown
*
* Creates the dropdown menu for the selection view
*
* #return the dropdown menu used in the view
*/
public JComboBox createDropdown() {
String[] sport = { "Table Tennis", "BasketBall" };
JComboBox cb = new JComboBox(sport);
return cb;
}
}
Make sure you are initialise (and updating) the UI from within the context of the Event Dispatching Thread.
See Initial Threads for more details.
EventQueue.invokeAndWait(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
// Create the UI here
}
});
Also, if possible, call setVisible on the window last, after you have established the basic UI. If the UI is dynamic, you will need to call revalidate and repaint on the parent container that you are adding your components to or consider using a CardLayout
Some video drivers can cause problems on some platforms, if problems persist, consider providing a runnable example which demonstrates your problem. This will result in less confusion and better responses
My image was displaying properly before I had a JButton on top of it. Now that I have added a JButton to my code, my image does not display. In the ActionPerformed method I am telling the button to setVisbible(false). When I click the button, it disapears and all that is behind it is the background.
public class Main extends JFrame implements ActionListener {
public static void main(String[] args) {
Main main = new Main();
}
ImageIcon GIF = new ImageIcon("src/Zombie Steve gif.gif");
JButton button = new JButton("Click me!");
JLabel Label = new JLabel(GIF);
public Main() {
button.addActionListener(this);
Label.setHorizontalAlignment(0);
JFrame Frame = new JFrame("zombieSteveGIF");
Frame.setSize(650, 650);
Frame.setVisible(true);
Frame.add(Label);
Frame.add(button);
Frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
while (true) {
Frame.getContentPane().setBackground(Color.BLUE);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame.getContentPane().setBackground(Color.GREEN);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame.getContentPane().setBackground(Color.RED);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void actionPerformed(ActionEvent e) {
button.setVisible(false);
}
}
Your problem is that you have a BorderLayout (the default for JFrames), and you are adding two components in the same position. The default is BorderLayout.CENTER, and by adding two components with just the default constraints, the first one is removed and the second put in its place.
As for fixing your problem, what do you want to achieve? If you want the components to show on top of one another, you can use the OverlayLayout. If you don't want this, try some other layout manager.