Как отобразить цвет последней нажатой кнопки в java?

#java

Вопрос:

Необходимо, чтобы при перезапуске приложения отображался последний отображаемый цвет.

 import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io. *;

public class The extends JFrame {
    private JButton st1=new JButton("26");

    public The() {
        JPanel panel=new JPanel();
        panel.add(st1);
        st1.addActionListener(new Ac());
        add(panel);
    }

    class Ac implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            if (((Component)source).getBackground().equals(Color.red)){
                ((Component)source).setBackground(null); //the color changing
            } else {
                ((Component)source).setBackground(Color.red);
            }
            try { //Here I threw the state of the button into color1.txt. The color of the button
                FileOutputStream f = new FileOutputStream("color1.txt");
                ObjectOutputStream out = new ObjectOutputStream(f);
                out.writeObject(st1);
                System.out.println("File has been writen");
                out.close();
            } catch (IOException o) {
        }
    }

    public static void main(String[] args) throws IOException {
        The window = new The();
        window.setVisible(true);
        window.setSize(400,600);
        FileInputStream fileInputStream = new FileInputStream("color1.txt");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
    }
}
 

Теперь вам нужно отобразить цвет, который был до закрытия при перезапуске окна. То есть, если цвет кнопки был красным, чтобы отобразить красный. Если цвет кнопки нормальный, отображается нормальный цвет.

Комментарии:

1. Вам нужно прочитать объект из потока ввода объекта. JLabel label = (JLabel)objectInputStream.readObject();

2. Ответ на вопрос о названии состоит в том, чтобы записать цвет в постоянное хранилище и прочитать значение при запуске приложения. Похоже, вы пытаетесь это сделать (используя файл), но, по-видимому, это работает не так, как предполагалось, но вы не описываете несоответствие. Подумайте о том, чтобы написать метод для чтения значения и другой метод для записи значения. Вызовите соответствующий метод при запуске и завершении работы.

Ответ №1:

Сначала код, потом объяснения.

 import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class The extends WindowAdapter implements ActionListener, Runnable {
    private static final String  PATH = "color1.dat";

    private Color  defaultBackground;
    private JButton  st1;
    private JFrame  frame;

    @Override // java.awt.event.ActionListener
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        if (source == st1) {
            Color col = st1.getBackground();
            if (col == defaultBackground) {
                st1.setBackground(Color.red);
            }
            else {
                st1.setBackground(defaultBackground);
            }
        }
    }

    @Override // java.lang.Runnable
    public void run() {
        createAndDisplayGui();
    }

    @Override // java.awt.event.WindowAdapter
    public void windowClosing(WindowEvent event) {
        Color background = st1.getBackground();
        try (FileOutputStream fos = new FileOutputStream(PATH);
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(background);
        }
        catch (IOException xIo) {
            throw new RuntimeException("Failed to save button background.", xIo);
        }
    }

    private void createAndDisplayGui() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addWindowListener(this);
        st1 = new JButton("26");
        st1.addActionListener(this);
        defaultBackground = st1.getBackground();
        init();
        JPanel panel = new JPanel();
        panel.add(st1);
        frame.add(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void init() {
        try (FileInputStream fis = new FileInputStream(PATH);
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            Object obj = ois.readObject();
            if (obj instanceof Color) {
                Color bg = (Color) obj;
                st1.setBackground(bg);
            }
        }
        catch (FileNotFoundException xFileNotFound) {
            // Ignore.
        }
        catch (ClassNotFoundException | IOException x) {
            throw new RuntimeException("Failed to read saved background", x);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new The());
    }
}
 
  • В методе main я явно запускаю поток отправки событий (EDT). Параметр для метода invokeLater является экземпляром класса, реализующего интерфейс java.lang.Runnable (что The делает класс). Следовательно, метод invokeLater вызовет метод run в классе The .
  • Метод run (в классе The ) вызывает метод createAndDisplayGui . В этом методе я создаю графический интерфейс.
  • Метод createAndDisplayGui вызывает метод init . Метод init пытается прочитать файл, в котором хранится последний цвет фона st1 (т. е. JButton ). Обратите внимание, что в коде используются методы «попытка с ресурсами» и «множественный захват«. Также обратите внимание, что при первом запуске приложения файл может не существовать. Поэтому я игнорирую FileNotFoundException .
  • Вы действительно хотите сохранить цвет фона только st1 при выходе из приложения. Поэтому я добавил список окон. Метод windowClosing вызывается непосредственно перед JFrame закрытием.