Saving changes made in a JFrame - java

I have a simple JFrame where the user is changing the background color of it using a JPopupMenu. When the user exit the application, I want to save the changes made in the background.
I have tried to handle this with method windowClosing() from WindowAdapter class but when when I launch the application again, I don't see the changes I made earlier. I don't know what the problem is. I will appreciate any help. Here's my code.
/*i have removed unnnecessary codes*/
public class Popupframe extends JFrame{
private JRadioButtonMenuItem[] items;
private final Color[] colorvalues={Color.BLUE,Color.YELLOW,Color.RED};
static Color bgcolor=Color.CYAN;
JRadioButtonMenuItem[] cheek;
public Popupframe() {
super("using popups");
String[] colors = {"Blue","Yellow","Red"};
setBackground(bgcolor);
addMouseListener(new Handler());
}
private class Handler extends MouseAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
for(int i=0; i<items.length; i++) {
if(event.getSource()==items[i]) {
getContentPane().setBackground(colorvalues[i]);
bgcolor=colorvalues[i];
}
}
}
}
public static void main(String[] args) {
Popupframe frame=new Popupframe();
frame.setSize(width,height);
frame.setDefaultCloseOperation(Popupframe.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int ok=JOptionPane.showConfirmDialog(frame,"are sure?","close",JOptionPane.WARNING_MESSAGE);
if(ok==JOptionPane.OK_OPTION) {
bgcolor=frame.getContentPane().getBackground();
System.out.println(bgcolor);
System.exit(0);
}
}
});
frame.setVisible(true);
}

You need to save the color code into a file(like settings file or shared preference) before System.exit(0) and read it in the main and set that color code. Then it works fine.

You are not persisting the color. Color is serializable, so you could just save the object in the program root directory. Put this code in your WindowClosing method :
//serialize the Color
try (
OutputStream file = new FileOutputStream("myBgColor.ser");
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
){
output.writeObject(bgColor);
}
catch(IOException ex){
log.log(Level.SEVERE, "Cannot perform output.", ex);
}
When you reload the application you need to get the color back. In the PopupFrame() constructor, before you call setBackground(color), put in this code here :
//deserialize the Color file
try(
InputStream file = new FileInputStream("myBgColor.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
){
//deserialize the List
bgColor = (Color)input.readObject();
}
catch(ClassNotFoundException ex){
fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex);
}
That should do the trick.

Related

Jave FileNotFoundException(Access Denied)

I have created a AWT frame which accepts text input in textarea and can count the number of words and characters or it could save its content to "trial.txt" file.
This is the whole code for reference:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class trial extends Frame
{
static TextArea ta=new TextArea("Welcome");
static Label l1=new Label("Words:");
static Label l2=new Label("Characters:");
static Button b=new Button("Count");
static Button save=new Button("Save");
static BufferedOutputStream bos;
trial()
{
//Setting position
ta.setBounds(300,300,300,300);
l1.setBounds(50,50,100,100);
l2.setBounds(50,200,100,100);
b.setBounds(650,300,50,50);
save.setBounds(650,400,50,50);
//Setting up file for saving
try {
bos=new BufferedOutputStream(new FileOutputStream("C:\\trial.txt"));
} catch (Exception e) {
e.printStackTrace();
}
save.addActionListener(new Save());
//Adding the components
this.add(ta);
this.add(l1);
this.add(l2);
this.add(b);
this.add(save);
//adding actionlistener to button
b.addActionListener(new actionlistener());
//setting up frame
this.setSize(1000,1000);
this.setLayout(null);
this.setVisible(true);
}
public static class actionlistener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
String text=ta.getText();
String words[]=text.split("\\s");
l1.setText("Words:"+words.length);
l2.setText("Characters:"+text.length());
}
}
public static class Save implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
String text=ta.getText();
byte[] arr=text.getBytes();
try
{
bos.write(arr);
} catch (IOException f)
{
}
}
}
public static void main(String args[])
{
trial ttt=new trial();
}
}
I have copied the right path, it is given above in the code. I have also given permission to java to read and write. But the code shows java.io.FileNotFoundException: C:\trial.txt (Access is denied) .
Oh it was very easy just a silly mistake.
Needed to put file name as parameter and not file path.
It is showing no error now but it is not saving the contents of the file to the txt file.
*Edit:It is working now.Thank you all for your help.

Problem with downloading and displaying image

I have made a program in Java, that downloads an image from the internet, given a link, and saves it into a specific folder in my computer, upon the pressing of a button in the gui. What I want to do next is to display that image on the screen. Please note, the URL input is not necessarily the URL of the image itself, but of an HTML webpage containing the image. The problem is, I can't simply create an ImageIcon object preemptively, because the image file doesn't exist in the system yet in compile time.
Panel Class
public class AdditionPanel extends JPanel
{
// ...
static JTextPane textpane;
JLabel paneInstructions;
JButton linkOk;
public AdditionPanel() throws IOException
{
textpane = new JTextPane();
paneInstructions = new JLabel("Paste the link here:");
linkOk = new JButton(" OK ");
// ...
linkOk.addActionListener(new LinkOkPressed());
// ...
this.add(textpane);
this.add(paneInstructions);
this.add(linkOk);
}
}
An idea I've had is to create an ActionListener for that button, and try to access the file only after the button has been pressed, and thus the file has been downloaded. In this case, I don't know how to make an image display on a JPanel, from a different class.
Action Listener
public class LinkOkPressed implements ActionListener
{
JLabel test;
#Override
public void actionPerformed(ActionEvent e)
{
// ImageDownloader is a class I have created, that simply saves the image
// from the given URL in a predetermined directory
ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
ImageIcon poster = new ImageIcon(getClass().getResource("/resources/myimage.png"));
test= new JLabel(poster);
AdditionPanel.add(test); // Does not work
}
}
So, can I add an image to the panel from a different class, or is there a better way to access a file that is downloaded during the runtime of the app? Thanks for the help.
ImageDownloader
public class ImageDownloader
{
public static String getImageUrl(String imdbLink)
{
String imageLink = "";
try
{
Document doc = Jsoup.connect(imdbLink).get();
Elements divs = doc.getElementsByClass("poster");
Element poster = divs.first();
Elements image = poster.getElementsByTag("a");
Element downloadImage = image.first();
Elements img = downloadImage.getElementsByTag("img");
imageLink = img.attr("src");
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageLink;
}
public static void saveImage(String imageLink)
{
BufferedImage image = null;
try
{
URL url =new URL(imageLink);
image = ImageIO.read(url);
ImageIO.write(image, "png", new File("C:\\...\\resources\\myimage.png"));
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Elaborating on PM 77-1's comment.
public class LinkOkPressed implements ActionListener
{
JLabel test;
#Override
public void actionPerformed(ActionEvent e)
{
// ImageDownloader is a class I have created, that simply saves the image
// from the given URL in a predetermined directory
ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
ImageIcon poster = new ImageIcon(getClass().getResource("/resources/myimage.png"));
test= new JLabel(poster);
Object obj = e.getSource(); // "obj" is really "linkOk" from class "AdditionPanel"
java.awt.Container parent = ((JButton) obj).getParent(); // "parent" is instance of "AdditionPanel"
((JPanel) parent).add(test);
}
}
SwingWorker example.
Create a separate class like so...
public class SaveImage extends javax.swing.SwingWorker<Void, Void> {
private AdditionPanel additionPanel;
public SaveImage(AdditionPanel addPanel) {
additionPanel = addPanel;
}
#Override
protected Void doInBackground() throws Exception {
ImageDownloader.saveImage(ImageDownloader.getImageUrl(AdditionPanel.textpane.getText()));
// Wait until the image is saved.
// Since I don't have code for class "ImageDownloader", can't tell you how to do this.
return null;
}
#Override
protected void done() {
javax.swing.ImageIcon poster = new javax.swing.ImageIcon(getClass().getResource("/resources/myimage.png"));
javax.swing.JLabel test= new javax.swing.JLabel(poster);
additionPanel.add(test);
}
}
And change your LinkOkPressed class like so...
public class LinkOkPressed implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource(); // "obj" is really "linkOk" from class "AdditionPanel"
java.awt.Container parent = ((JButton) obj).getParent(); // "parent" is instance of "AdditionPanel"
SaveImage saveImage = new SaveImage((AdditionPanel) parent);
saveImage.execute();
}
}

Cant append to JTextArea

I'm trying to create a text chat with Java. I have a Server and a Client that connect to each other using Streams, and send data using the objectInputStream and objectOutputStream.
I have GUI's for both the client and the server.
I made these GUI's using intellij's GUI Form.
server GUI form image
The problem I'm having is when I try to display text to the GUI of the server. I can append to the GUi if I call my relayToAll method from the JTextField actionlistener, which then send the message to all the clients and prints it out in the servers GUI.
If i try to call the same method from where I receive the input, then the append to the text area does not work.
Can anyone tell me why its not appending?
Thanks
public class ServerTest {
private JTextField textField1;
private JTextArea textArea1;
private JPanel Panel;
static private ObjectOutputStream objectOutputStream;
static private ObjectInputStream objectInputStream;
static private Socket client;
static private ArrayList<Socket> clients = new ArrayList<Socket>();
static private ArrayList<ObjectOutputStream> objectOutputStreams = new ArrayList<>();
public void relayToAll(String message){
try {
for(int i = 0; i < clients.size(); i++) {
ObjectOutputStream output = objectOutputStreams.get(i);
output.writeObject(message);
output.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
appendTextArea(message);
}
public void appendTextArea(String text){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
System.out.println("This should go to the Server GUI: " + text);
textArea1.append(text + "\n");
}
});
}
public ServerTest() {
textField1.addActionListener(e -> {
System.out.println(e.getActionCommand());
relayToAll(e.getActionCommand());
textField1.setText("");
});
}
public void ReadInput(ObjectInputStream input, int port){
try {
String oldMessage = "";
while (true) {
String message = (String) input.readObject();
if (message != oldMessage){
System.out.println(port + ": " + message);
oldMessage = message;
relayToAll(port + ": " + message);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void IOSetup(){
try {
ServerSocket serverSocket = new ServerSocket( 6969 );
ExecutorService executor = Executors.newFixedThreadPool(5);
System.out.println("server on\n");
for (int i = 0; i < 5; i++){
client = serverSocket.accept();
clients.add(client);
System.out.println("Connection from: "+ client.getPort());
objectOutputStream = new ObjectOutputStream(client.getOutputStream());
objectOutputStreams.add(objectOutputStream);
objectInputStream = new ObjectInputStream(clients.get(i).getInputStream());
executor.submit(() -> {
ReadInput(objectInputStream, client.getPort());
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Server");
frame.setContentPane(new ServerTest().Panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
ServerTest application = new ServerTest();
application.IOSetup();
}
Actually you've got kind of a silly mistake. Please check lines (A) and (B) below:
public static void main(String[] args) {
JFrame frame = new JFrame("Server");
frame.setContentPane(new ServerTest().Panel); // *************** (A)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
ServerTest application = new ServerTest(); // *************** (B)
application.IOSetup();
}
Do you see a problem? You're creating TWO ServerTest objects, one that has its Panel variable added to the JFrame and that gets displayed, and the other that is set up for IO communication. The ActionListener changes the state of the displayed JTextArea while the IO communications changes the state of a JTextArea that is in the second ServerTest instance, the one not displayed.
One improvement is to create only one instance:
public static void main(String[] args) {
ServerTest application = new ServerTest(); // create one instance
JFrame frame = new JFrame("Server");
// frame.setContentPane(new ServerTest().Panel);
frame.setContentPane(application.Panel); // and use in both places
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
//ServerTest application = new ServerTest();
application.IOSetup(); // and use in both places
}
Other problems:
You've got long-running code long running and blocking in a background thread, and that is potentially dangerous, and the only reason that your GUI is not getting frozen is because you're starting the GUI (incorrectly) on the main thread and off of the Swing event thread. For more on this, you will want to read up on Swing concurrency: Lesson: Concurrency in Swing
You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.

unable to stop stream when i DISPOSE_ON_CLOSE

I am trying to stop the stream when i close the jframe. i do not want to EXIT_ON_CLOSE beacuse i do not want to exit my application. When i use DISPOSE_ON_CLOSE the frame closes but the audiostream keeps on playing. Is there a way to stop this stream without the use of some external button.(i want to close the stream just by clicking "X" on the jframe).
Thank you for help.
public class MediaPlayer {
private JFrame ourFrame = new JFrame();
private EmbeddedMediaPlayerComponent ourMediaPlayer;
private String mediapath = "";
MediaPlayer(String vlcPath,String mediaURL) {
this.mediapath = mediaURL;
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
ourMediaPlayer = new EmbeddedMediaPlayerComponent();
ourFrame.setContentPane(ourMediaPlayer);
ourFrame.setSize(1200, 800);
ourFrame.setVisible(true);
ourFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public void run() {
ourMediaPlayer.getMediaPlayer().playMedia(mediapath);
}
}
You can handle your stream closing operation on window close, with below:
ouFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
// close/stop audio stream here
System.out.println("closed");
}
});

Java cant write in a .txt

hello i desperately need your help,well i have a jframe with a jcombobox and 3 textfields i want anything i write in the textfields and the choice i make in the combobox to be written in a .txt i tried so many things but nothing , the file is being created as Orders.txt but remains blank :S this is my code i appreciate any help Thanks :)
public class addSalesMan extends JFrame {
private JComboBox namesJComboBox;
private JTextField text1;//gia to poso
private JTextField text2;//thn perigrafh
private JTextField text3;//kai to numero ths paragelias kai ola auta tha egrafontai sto Orders.txt
private JButton okJbutton;
private String names[] = {"Basilis Komnhnos", "Iwanna Papadhmhtriou"};
public String amount,name,description,number;
public addSalesMan() {
super("Προσθήκη παραγγελιών");
setLayout(new FlowLayout());//dialegoume to flowlayout
// TextFieldHandler handler = new TextFieldHandler(); writer.write(string);
//ftiaxonoume to combobox gia tn epilogi tou onomatos
namesJComboBox = new JComboBox(names);//orizmos JCOMBO BOX
namesJComboBox.setMaximumRowCount(2);//na emfanizei 2 grammes
add(namesJComboBox);
namesJComboBox.addItemListener(new ItemListener() {
//xeirozome to simvan edw dhladh tn kataxwrisei ston fakelo
public void itemStateChanged(ItemEvent event) {
//prosdiorizoyme an eina epilegmeno to plaisio elegxou
if (event.getStateChange() == ItemEvent.SELECTED) {
name = (names[namesJComboBox.getSelectedIndex()]);
// writer.newLine();
setVisible(true);
}
}
}); //telos touComboBOx
//dimioutgw pediou keimenou me 10 sthles gia thn kathe epilogh kai veveonomaste oti tha mporoume na ta epe3ergasoume kanontas ta editable
text1 = new JTextField("Amount",10);
add(text1);
text2 = new JTextField("Description",10);
add(text2);
text3 = new JTextField("Order Number",10);
add(text3);
TextFieldHandler handler = new TextFieldHandler();
text1.addActionListener(handler);
text2.addActionListener(handler);
text3.addActionListener(handler);
//private eswterikh clash gia ton xeirismo twn events twn text
//button kataxwrisis
okJbutton=new JButton("Καταχώρηση");
add(okJbutton);
ButtonHandler bhandler=new ButtonHandler();
okJbutton.addActionListener(bhandler);
Order order=new Order(name,amount,description,number);
Order.addOrders(name,amount,description,number);
}
private class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent bevent ){
JOptionPane.showMessageDialog(addSalesMan.this,String.format("Η Καταχωρηση ήταν επιτυχής",bevent.getActionCommand()));
}
}
private class TextFieldHandler implements ActionListener {
//epe3ergasia twn simvantwn me kathe enter t xrhsth
public void actionPerformed(ActionEvent evt) {
String amount,description,number;
amount=text1.getText();
description=text2.getText();
number=text3.getText();
text1.selectAll();
text2.selectAll();
text3.selectAll();
}
if(evt.getSource()==text1 && evt.getSource()==text2 && evt.getSource()==text3){
JOptionPane.showMessageDialog(addSalesMan.this,String.format("Η Καταχωρηση ήταν επιτυχής",evt.getActionCommand()));
}
}
//actionperformed telos
//ean o xrhsths patisei enter sthn kathe epilogh antistixi kataxwrisi sto
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new addSalesMan().setVisible(true);
}
});
}
}
The writers are in another class. Here is the relevant code:
public static void addOrders(String name,String amount,String description,String o_number){
FileOutputStream fout;
try {
FileWriter fstream = new FileWriter("Orders.txt");
if(name!=null){
BufferedWriter out = new BufferedWriter(fstream);
out.write(name);
out.write(amount);
out.write(description);
out.write(o_number);
out.write("\t\n");
out.close();
}
} catch (IOException e) {
System.err.println ("Unable to write to file");
System.exit(-1);
}
}
It looks like the main problem is that you are calling Order.addOrders() in your constructor. Instead, you should call it when a user chooses to save it's selection. I assume you would like this to happen when the user presses the button. So the code should be added in the button's ActionListener.
What you might need to try is flushing and closing the writer when a user closes your frame.
Add the following to the constructor of your frame:
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
writer.flush();
writer.close();
}
});
The above code will flush and close the writer when a user closes the frame.
Your code is unclear, so I'm not sure where the writer variable is declared, I'm just assuming it is a class level variable.
Also, you need to open your file in 'append' mode if you want to add lines to the file instead of overwriting it every time. This can be achieved through the following:
new FileWriter(yourFilePath, true); // set append to true

Categories