I'm making a program that is saving an array of JButtons to a file .btn. here is the code that is being saved:
package avtech.software.compunav;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.swing.JButton;
public class Buttons implements Serializable {
public static Button[] buttons = new Button[15];
public Buttons() {
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new Button();
buttons[i].setText("Unassigned");
}
}
public JButton[] getButtons() {
return buttons;
}
public JButton getButton(int index) {
return buttons[index];
}
public void setButtonText(String txt, int index) {
buttons[index].setText(txt);
}
public void setButtonAction(String action, int index) {
}
public void save() {
try {
File dir = new File(Core.baseDir + "/bin/buttons.btn");
FileOutputStream fos = new FileOutputStream(dir);
ObjectOutputStream oos = new ObjectOutputStream(fos);
if (dir.exists())
dir.delete();
oos.writeObject(this);
oos.flush();
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Button is a class that extends JButton, and here is that code:
package avtech.software.compunav;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.swing.JButton;
import CompuNav.main.Dialogs;
public class Button extends JButton implements ActionListener {
private String action = "";
public Button() {
addActionListener(this);
}
public void setAction(String s) {
action = s;
}
#Override
public void actionPerformed(ActionEvent arg0) {
if (action.equals(""))
return;
File file = new File(action);
Desktop dt = Desktop.getDesktop();
try {
dt.open(file);
} catch (IOException e1) {
Dialogs.msg("Could not open " + action);
}
}
}
Basically, the code is saving. there is a file called buttons.btn in the correct directory. The problem is, when I use the load method here:
try {
FileInputStream fis = new FileInputStream(baseDir
+ "/bin/buttons.btn");
ObjectInputStream ois = new ObjectInputStream(fis);
buttonsClass = (Buttons) ois.readObject();
ois.close();
} catch (Exception e) {}
after making a new object of the Buttons and saving it, I get a nullPointerException when trying to call buttonsClass.getButton(0);, implying that the JButtons are not saved when i save the class.
Any reason as to why, and any idea how to fix this?
public static Button[] buttons = new Button[15];
This variable should not be static if you want it to be serialized.
Related
I know I must be missing something very obvious, but whenever I try to use the ProgressMonitorInputStream when copying a file, I never get the ProgressDialog popup.
The examples I see don't seem to do much other than wrap their input stream within the ProgressMonitorInputStream.
The docs say:
This creates a progress monitor to monitor the progress of reading the input stream. If it's taking a while, a ProgressDialog will be popped up to inform the user. If the user hits the Cancel button an InterruptedIOException will be thrown on the next read. All the right cleanup is done when the stream is closed.
Here is an extremely simple example I put together that never pops up the dialog with a large file even if I setMillisToPopup() to an insanely small number.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.ProgressMonitorInputStream;
import javax.swing.SwingWorker;
public class ProgressBarDemo extends JFrame {
private static final long serialVersionUID = 1L;
private JButton button;
ProgressBarDemo()
{
button = new JButton("Click me!");
ButtonActionListener bal = new ButtonActionListener();
button.addActionListener(bal);
this.getContentPane().add(button);
}
private class ButtonActionListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Worker worker = new Worker();
worker.execute();
button.setEnabled(false);
}
}
public void go() {
this.setLocationRelativeTo(null);
this.setVisible(true);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private class Worker extends SwingWorker<Void, Void>
{
private void copyFile() {
File file = new File("/Users/mypath/Desktop/WirelessDiagnostics.tar.gz");
BufferedInputStream bis;
BufferedOutputStream baos;
try {
bis = new BufferedInputStream(new FileInputStream(file));
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(
ProgressBarDemo.this,
"Reading... " + file.getAbsolutePath(),
bis);
pmis.getProgressMonitor().setMillisToPopup(10);
baos = new BufferedOutputStream(new FileOutputStream("/Users/mypath/Desktop/NewWirelessDiagnostics.tar.gz"));
byte[] buffer = new byte[2048];
int nRead = 0;
while((nRead = pmis.read(buffer)) != -1) {
baos.write(buffer, 0, nRead);
}
pmis.close();
baos.flush();
baos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected Void doInBackground() throws Exception {
// TODO Auto-generated method stub
copyFile();
return null;
}
#Override
protected void done() {
button.setEnabled(true);
}
}
}
public class TestProj {
public static void main(String[] args) {
ProgressBarDemo demo = new ProgressBarDemo();
demo.go();
}
}
Any suggestions?
You are calling copyFile from within the context of the Event Dispatching Thread, this means the EDT is unable to respond to new events or paint requests until after the method returns.
Try placing the call within it's own Thread context...
Thread t = new Thread(new Runnable(
public void run() {
copyFile();
}
));
t.start();
Equally, you could use a SwingWorker, it's a little bit of overkill, but you get the benefit of the PropertyChangeListener or it's done method, which could be used to re-enable the JButton, should you want to prevent people from clicking the button while a copy operation is in progress
See Concurrency in Swing and Worker Threads and SwingWorker for more details
Updated with example
Copying a 371mb file, across the local disk...
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.ProgressMonitorInputStream;
import javax.swing.SwingWorker;
public class ProgressBarDemo extends JFrame {
private static final long serialVersionUID = 1L;
private JButton button;
ProgressBarDemo() {
button = new JButton("Click me!");
ButtonActionListener bal = new ButtonActionListener();
button.addActionListener(bal);
this.getContentPane().add(button);
}
public void go() {
this.setLocationRelativeTo(null);
this.setVisible(true);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void copyFile() {
File file = new File("...");
BufferedInputStream bis;
BufferedOutputStream baos;
try {
bis = new BufferedInputStream(new FileInputStream(file));
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(
this,
"Reading... " + file.getAbsolutePath(),
bis);
pmis.getProgressMonitor().setMillisToPopup(10);
baos = new BufferedOutputStream(new FileOutputStream("..."));
byte[] buffer = new byte[2048];
int nRead = 0;
while ((nRead = pmis.read(buffer)) != -1) {
baos.write(buffer, 0, nRead);
}
pmis.close();
baos.flush();
baos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class ButtonActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
SwingWorker worker = new SwingWorker() {
#Override
protected Object doInBackground() throws Exception {
copyFile();
return null;
}
#Override
protected void done() {
button.setEnabled(true);
}
};
worker.execute();
}
}
public static void main(String[] args) {
ProgressBarDemo demo = new ProgressBarDemo();
demo.go();
}
}
Remember, there is overhead involved in setting up the window and displaying, which needs to be factored in. The system may "want" to display a window, but by the time the system has set it up and is prepared to display it, the steam may have finished copying...
Extended Example
nb: I don't really like the ProgressMonitor API as I've not been able to find where the UI is synchronised with the EDT, this can cause issues in Java 7 & 8
You could formalise the idea into a self contained worker, for example...
public class CopyWorker extends SwingWorker {
private File source;
private File dest;
private Component parent;
private ProgressMonitorInputStream pmis;
public CopyWorker(Component parent, File source, File dest) {
this.parent = parent;
this.source = source;
this.dest = dest;
}
#Override
protected Object doInBackground() throws Exception {
try (InputStream is = new FileInputStream(source)) {
try (OutputStream os = new FileOutputStream(dest)) {
pmis = new ProgressMonitorInputStream(
parent,
"Copying...",
is);
pmis.getProgressMonitor().setMillisToPopup(10);
byte[] buffer = new byte[2048];
int nRead = 0;
while ((nRead = pmis.read(buffer)) != -1) {
os.write(buffer, 0, nRead);
}
}
}
return null;
}
#Override
protected void done() {
try {
pmis.close();
} catch (Exception e) {
}
}
}
This attempts to contain the functionality, but also deals with the cleanup of the ProgressMonitorInputStream within the done method, making sure that it's done within the EDT. I'd personally attach a PropertyChangeListener to it and monitor the done property to determine when the worker has completed and examine the return result in order to pick up any exceptions, this gives you the ability to handle the exceptions in your own way and de-couples the worker from your process
Your program works on files, but when it comes to server and client streams, it
fails.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.ProgressMonitorInputStream;
import javax.swing.SwingWorker;
public class FileReceive extends JFrame {
private static final long serialVersionUID = 1L;
private BufferedInputStream bufferInput;
private FileOutputStream fout;
private BufferedOutputStream bufferOutput;
private Socket client;
private JButton button;
private File fileinfo;
ProgressMonitorInputStream pois;
FileReceive() {
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
receiveFile();
}
public static void main(String arg[]) {
new FileReceive();
}
public void receiveFile() {
try {
fileinfo=new File(filepath);
client=new Socket("localhost",9090);
fout=new FileOutputStream(fileinfo);
bufferOutput=new BufferedOutputStream(fout);
bufferInput=new BufferedInputStream(client.getInputStream());
pois=new ProgressMonitorInputStream(this, "reading", bufferInput);
int ch;
byte[] b=new byte[2048];
System.out.println("Receiving File");
while(-1!=(ch=pois.read(b))) {
bufferOutput.write(b,0,ch);
}
pois.close();
bufferInput.close();
bufferOutput.close();
fout.close();
client.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
}
how can I show a JProgressBar component like on the loading of a bin file?
I can only found solutions for iterative bin read and I'm using an object reading like:
CustomObj test = (CustomObj) in.readObject();
Cheers
If you can't measure the progress of the process, then you can only specify the "indeterminate mode" of the progress bar. When in this mode, the progress bar will indicate that it is working, but the completion of the process is unknown.
JProgressBar progress = new JProgressBar();
progress.setIndeterminate(true);
I recommend to do two things:
Creating a wrapping class around your original inputstream so that you can monitor the bytes that are read from it. Basically, you extends InputStream and delegate everything to the original stream (except a few methods) and in the read() method, you make sure that you notify some listener.
I guess that if you want a progress bar, it means that the loading operation takes a while and you want to provide feedback to the user. Long running task cannot run directly on the EDT (so typically, you cannot perform your task in an actionPerformed method). You therefore need to delegate the work to another Thread, by using a SwingWorker for example. If you don't this, then the UI will freeze and the feedback will not be viewable by the user.
This being, said it may seem complex or not trivial. Therefore, here some short example, that illustrates all this and works:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class TestProgressBar {
// Some simple listener interface to get a callback as bytes are being read
public static interface ProgressListener {
public void notifyByteRead();
}
// The wrapping input stream that will call the listener as bytes are being read
public static class ProgressInputStream extends InputStream {
private InputStream in;
#Override
public int read() throws IOException {
int read = in.read();
if (read > -1) {
// Here we notify the listener
listener.notifyByteRead();
}
return read;
}
#Override
public long skip(long n) throws IOException {
return in.skip(n);
}
#Override
public int available() throws IOException {
return in.available();
}
#Override
public void close() throws IOException {
in.close();
}
#Override
public void mark(int readlimit) {
in.mark(readlimit);
}
#Override
public void reset() throws IOException {
in.reset();
}
#Override
public boolean markSupported() {
return in.markSupported();
}
private ProgressListener listener;
public ProgressInputStream(InputStream in, ProgressListener listener) {
this.in = in;
this.listener = listener;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
init();
}
});
}
public static void init() {
// 1. Let's create a big object with lots of data
List<Long> object = new ArrayList<Long>();
Random random = new Random();
for (int i = 0; i < 1e6; i++) {
object.add(random.nextLong());
}
// 2. We write it to a temp file
File tempFile = null;
ObjectOutputStream oos = null;
try {
tempFile = File.createTempFile("Test", ".bin");
tempFile.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tempFile);
oos = new ObjectOutputStream(new BufferedOutputStream(fos));
oos.writeObject(object);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (tempFile == null) {
System.exit(1);
}
// 3. Now let's build a UI to load that
final File theFile = tempFile;
JFrame frame = new JFrame("Test ghost text");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
final JProgressBar bar = new JProgressBar(0, (int) tempFile.length());
JButton button = new JButton("load");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
bar.setValue(0);
// Declare and implement a Swing worker that will run in another thread
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
#Override
protected void process(List<Integer> chunks) {
// Here we are on the EDT, so we can safely notify the progressbar
super.process(chunks);
bar.setValue(bar.getValue() + chunks.size());
}
#Override
protected Void doInBackground() throws Exception {
// Here we are not in the EDT, we perform the task but don't modify anything in the UI
ProgressInputStream pis = new ProgressInputStream(new BufferedInputStream(new FileInputStream(theFile)),
new ProgressListener() {
#Override
public void notifyByteRead() {
publish(1); // the value that is sent here could be anything, we don't use it.
}
});
ObjectInputStream ois = new ObjectInputStream(pis);
try {
List<Long> readObject = (List<Long>) ois.readObject();
System.err.println("Loaded " + readObject.size() + " long values");
} catch (Exception e) {
e.printStackTrace();
} finally {
pis.close();
}
return null;
}
};
// Start the worker
worker.execute();
}
});
panel.add(bar);
panel.add(button, BorderLayout.EAST);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
Subclass java.io.FilteredInputStream to count the number of bytes being read and insert it between your ObjectInputStream and the underlying InputStream being read.
You can update the progress bar by sampling the running count or using a callback built in to your subclass.
Example:
public class CountingInputStream extends FilteredInputStream {
private int numBytes;
public CountingInputStream(InputStream inputStream){
this(inputStream);
}
public int getNumBytes(){
return numBytes;
}
#Override
public int read() {
int b = super.read();
if(b != -1){
countBytes(1);
}
return b;
}
#Override
public int read(byte[] b){
int n = super.read(b);
if(n >= 0){
countBytes(n);
}
return n;
}
#Override
public int read(byte[] b, int off, int len){
int n = super.read(b, off, len);
if(n >= 0){
countBytes(n);
}
return n;
}
private void countBytes(int n){
numBytes += n;
}
}
It could be used like below (assume InputStream is your source of data).:
InputStream is = ...;
CountingInputStream cis = new CountingInputStream(is)
ObjectInputStream ois = new ObjectInputStream(cis);
ois.readObject();
You can sample cis.getNumBytes() from a different thread (potentially with a Swing timer) and use the returned value to update a JProgressBar
I have an arraylist in my metod receiveArrayLists which i want to add to a JList. How can i do this?
import java.awt.Dimension;
import java.awt.Scrollbar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class GUI implements Runnable {
private Server server;
private JFrame frame = new JFrame();
private JTextField jtf = new JTextField();
private JList jl = new JList();
private JTextArea jl1 = new JTextArea();
private JScrollPane pane = new JScrollPane(jl);
private Socket socket;
private DataInputStream dis;
private ObjectInputStream ois = null;
private DataOutputStream dos;
public GUI() {
socket = new Socket();
InetSocketAddress ipPort = new InetSocketAddress("127.0.0.1", 4444);
try {
socket.connect(ipPort);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
} catch (Exception e) {
}
new Thread(this).start();
frame.getContentPane().setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(50, 300, 420, 400);
frame.setResizable(false);
frame.setVisible(true);
pane.add(jl);
pane.add(jl1);
jl1.setEditable(false);
jtf.setBounds(50, 40, 150, 40);
jl.setBounds(50, 90, 150, 200);
jl1.setBounds(210, 90, 150, 200);
jtf.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (dos != null) {
if(jtf.getText().length() >0){
try {
dos.writeUTF(jtf.getText());
} catch (IOException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
}
}else{
jl1.setText("");
}
}
}
});
frame.add(jtf);
frame.add(jl);
frame.add(jl1);
frame.add(pane);
}
public void run() {
String fromServer;
try {
while ((fromServer = dis.readUTF()) != null) {
if (fromServer.equals("read")) {
receiveArrayList();
}
}
} catch (Exception e) {
}
}
Here is my metod, as you can see, i try to use append which obviously wont work to add an arraylist to a JList
public void receiveArrayList() {
try {
jl1.setText("");
ois = new ObjectInputStream(socket.getInputStream());
#SuppressWarnings("unchecked")
ArrayList<String> a = (ArrayList<String>) (ois.readObject());
for (int i = 0; i < a.size(); i++) {
jl.append(a.get(i) + " \n");
}
dis = new DataInputStream(socket.getInputStream());
} catch (ClassNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
public static void main(String[] args) {
GUI g = new GUI();
}
}
The simplest is to create a DefaultListModel object, iterate through the ArrayList in a for or foreach loop and add the items to the model via its addElement(...) method. Then set the JList's model to your model.
More involved but satisfying is to create your own ListModel by extending AbstractListModel using your ArrayList as the model's nucleus.
You need to make use the JList's list model. The simplest solution is to use DefaultListModel, but you could investigate implementation your own (based on the AbstractListModel)
If you don't want to keep any previous content when you receive the array list you could do the following:
public void receiveArrayList() {
try {
DefaultListModel model = new DefaultListModel();
jl1.setText("");
ois = new ObjectInputStream(socket.getInputStream());
#SuppressWarnings("unchecked")
ArrayList<String> a = (ArrayList<String>) (ois.readObject());
for (int i = 0; i < a.size(); i++) {
model.addElement(a.get(i)); // <-- Add item to model
}
dis = new DataInputStream(socket.getInputStream());
jl.setModel(model); // <-- Set the model to make it visible
} catch (ClassNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
If you want to keep the previous list, then you need to ensure that the original model is a DefaultListModel (in this example) or is compatible with the ListModel you are using.
Basically, then you want to cast the model:
You may want to check out this tutorial for more info.
DefaultListModel model = jl.getModel();
Obviously, you won't need to reapply it at the end ;)
I'm having trouble linking the main page to the second page by the click of a button. It throws a NullPointException. Can someone please tell me where I've erred?
import java.io.InputStream;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.*;
import com.sun.lwuit.*;
import com.sun.lwuit.animations.CommonTransitions;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;
import java.io.IOException;
public class standings extends MIDlet implements ActionListener{
public Command cmdSelect;
public Form fform, selectLgform;
public Button btnSelectLeague,btnHelp,btnAbout,btnExit;
public TextArea taHome,taAbout, taHelp, taSelectLg;
private InputStream iStream;
private StringBuffer strBuffer;
private Form selectLgForm;
public void startApp() {
Display.init(this);
try {
Resources rs= Resources.open("/restheme.res");
UIManager.getInstance().setThemeProps(rs.getTheme("Theme2"));
} catch (Exception e) {
e.getMessage();
}
displayMainForm();
}
public void displayMainForm()
{
fform = new Form("Football League Standings");
taHome= new TextArea(5,20,TextArea.ANY);
fform.setLayout(new BorderLayout());
fform.setTransitionInAnimator(CommonTransitions.createFade(1000));
iStream = getClass().getResourceAsStream("/intro.txt");
strBuffer = new StringBuffer();
int next = 1;
try {
while((next = iStream.read()) != -1) {
char nextChar = (char) next;
strBuffer.append(nextChar);
}
} catch (IOException ex) {
ex.printStackTrace();
}
taHome.setText(strBuffer.toString());
strBuffer = null;
taHome.setFocusable(false);
taHome.setEditable(false);
taHome.setUIID("Label");
//fform.addComponent(BorderLayout.CENTER,taHome);
btnSelectLeague= (new Button("Select league"));
btnHelp= (new Button("Help"));
btnAbout= (new Button("About"));
btnExit= (new Button("Exit"));
Container mcont = new Container(new BoxLayout(BoxLayout.Y_AXIS));
mcont.addComponent(taHome);
mcont.addComponent(btnSelectLeague);
mcont.addComponent(btnHelp);
mcont.addComponent(btnAbout);
mcont.addComponent(btnExit);
fform.addComponent(BorderLayout.CENTER, mcont);
btnSelectLeague.addActionListener(this);
btnHelp.addActionListener(this);
btnAbout.addActionListener(this);
btnExit.addActionListener(this);
fform.show();
}
/* Command exitCommand = new Command("Exit");
fform.addCommand(exitCommand);
fform.addCommandListener(this);
}
}*/
public void selectLgForm()
{
selectLgForm= new Form("Select League");
taSelectLg= new TextArea(5,20,TextArea.ANY);
selectLgForm.setLayout(new BorderLayout());
selectLgForm.setTransitionInAnimator(CommonTransitions.createFade(1000));
iStream = getClass().getResourceAsStream("/selectlg.txt");
strBuffer = new StringBuffer();
int next = 1;
try {
while((next = iStream.read()) != -1) {
char nextChar = (char) next;
strBuffer.append(nextChar);
}
} catch (IOException ex) {
ex.printStackTrace();
}
taSelectLg.setText(strBuffer.toString());
strBuffer = null;
taSelectLg.setFocusable(false);
taSelectLg.setEditable(false);
taSelectLg.setUIID("Label");
selectLgForm.addComponent(BorderLayout.CENTER,taAbout);
//START OF MENU BUTTONS
selectLgForm.addCommand(new Command("Back")
{
public void actionPerformed(ActionEvent e)
{
displayMainForm();
}
});
selectLgForm.show();
}//END OF MENU BUTTONS
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void actionPerformed(ActionEvent ae) {
if(ae.getSource()==btnSelectLeague){
selectLgForm();
}
my best guesses are:
- selectLgForm.addComponent(BorderLayout.CENTER,taAbout) throws a NullPointerException because taAbout is null.
- or iStream = getClass().getResourceAsStream("/selectlg.txt"); throws a NullPointerException because the text file is not where you think it is.
I am trying to learn more about java. This program is an attempt to understand events as well as serialization. What i am attempting to do is flatten an object when the user closes the JFrame and re-inflate it when the program is started. I know i can create the serialized file but having it take effect again isn't working. Any help in the right direction would be wonderful. Thank you in advance.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.Timer;
import java.io.*;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class tempusFugit extends JFrame implements ActionListener, Serializable, WindowListener
{
String fileN = "tf.txt";
public int ToL = 0;
String outT = Integer.toString(ToL);
JLabel jl = new JLabel(outT);
FileOutputStream fos = null;
ObjectOutputStream out = null;
public tempusFugit()
{
Timer timer = new Timer(1000, this);
setBounds(250, 250, 250, 190);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.LEFT) );
setVisible(true);
add(jl);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
++ToL;
outT = Integer.toString(ToL);
jl.setText(outT);
validate();
repaint();
}
public static void main(String[] args)
{
tempusFugit tf = new tempusFugit();
tf.addWindowListener( tf );
}
public void windowDeactivated(WindowEvent e)
{
}
public void windowActivated(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
public void windowClosed(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
try
{
fos = new FileOutputStream(fileN);
out = new ObjectOutputStream(fos);
out.writeObject(this);
out.close();
}
catch(IOException ex)
{
}
}
public void windowOpened(WindowEvent e)
{
try
{
tempusFugit tf = new tempusFugit();
FileInputStream fis = new FileInputStream(fileN);
ObjectInputStream in = new ObjectInputStream(fis);
tf = (tempusFugit)in.readObject();
this.ToL = tf.ToL;
}
catch(IOException ex)
{
}
catch(ClassNotFoundException ce)
{
}
}
}
I assume i'm trying to recreate the object at the wrong time. Even though the object is serialized correctly i can not access it again with the windowOpened function. Do i need to try to use
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
somehow?
What i end up with is an error saying i am trying to access a Final object (i assume my this). I find that very odd that i cant repopulate my current 'this' with another similar object.
Am i way off base?
Again thank you for your time.
Note that there are much simpler ways to do this than serializing the frame, and much better things to serialize than the frame itself.
See What is the best practice for setting JFrame locations in Java? for an example of storing the location and size of a frame. It would be trivial to adapt that to store the count.
But here is an attempt based on your code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.Timer;
import java.io.*;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class tempusFugit extends JFrame implements ActionListener, Serializable, WindowListener
{
String fileN = "tf.txt";
public int ToL = 0;
JLabel jl = new JLabel("" + ToL);
public tempusFugit()
{
Timer timer = new Timer(1000, this);
setBounds(250, 250, 250, 190);
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.LEFT) );
setVisible(true);
add(jl);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
++ToL;
jl.setText("" + ToL);
validate();
repaint();
}
public static void main(String[] args)
{
tempusFugit tf = new tempusFugit();
tf.addWindowListener( tf );
}
public void windowDeactivated(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e)
{
try
{
FileOutputStream fos = new FileOutputStream(fileN);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(this);
out.flush();
out.close();
setVisible(false);
System.exit(0);
}
catch(IOException ex)
{
JOptionPane.showMessageDialog(null, ex);
System.exit(1);
}
}
public void windowOpened(WindowEvent e)
{
try
{
tempusFugit tf;// = new tempusFugit();
FileInputStream fis = new FileInputStream(fileN);
ObjectInputStream in = new ObjectInputStream(fis);
tf = (tempusFugit)in.readObject();
this.ToL = tf.ToL;
//tf.setVisible(false);
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(ClassNotFoundException ce)
{
ce.printStackTrace();
}
}
}