Java Swing - перерисовка из класса обработчика - PullRequest
0 голосов
/ 27 октября 2019

Итак, я начну с размещения здесь моего кода для моих двух классов.

SquareSimp.java


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

public class SquareSimp
{

    public static void main( String[] args )
    {
        FilledFrame frame = new FilledFrame();

        frame.setVisible( true );
    }
}

class FilledFrame extends JFrame
{
    int size = 400;

    public FilledFrame()
    {
        JButton butSmall   = new JButton("Small");
        JButton butMedium  = new JButton("Medium");
        JButton butLarge   = new JButton("Large");
        JButton butMessage = new JButton("Say Hi!");

        SquarePanel panel = new SquarePanel(this);
        JPanel butPanel = new JPanel();

        butSmall.addActionListener(new ButtonHandler1(this, 200){
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                size = 200;
                panel.repaint();
            }
        });

        butMedium.addActionListener(new ButtonHandler1(this, this.size){
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                size = 300;
                panel.repaint();
            }
        });

        butLarge.addActionListener(new ButtonHandler1(this, this.size){
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                size = 400;
                panel.repaint();
            }
        });



        butPanel.add(butSmall);
        butPanel.add(butMedium);
        butPanel.add(butLarge);
        butPanel.add(butMessage);
        add(butPanel, BorderLayout.NORTH);
        add(panel, BorderLayout.CENTER);

        setSize( size+100, size+100 );
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // Exercise 2.
        //Anonymous implementations of listeners are very efficient when you do not need to pass parameters to the
        // constructor of the implemented listener.
        butMessage.addActionListener(new ActionListener()
                // An anonymous function. Creates an actionListener that shows a dialog.
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                JOptionPane.showMessageDialog(null, "Hiiii");
            }
        });

    }

}

class SquarePanel extends JPanel
{
    FilledFrame theApp;

    SquarePanel(FilledFrame app)
    {
        theApp = app;
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.green);
        g.fillRect(20, 20, theApp.size, theApp.size);
    }
}

ButtonHandler1.java

package Lab2;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// This is a class whose object will handle the event.
public class ButtonHandler1 implements ActionListener{
    private FilledFrame theApp;
    private int theSize;
    ButtonHandler1(FilledFrame app, int size){
        theApp = app;
        theSize = size;
    }

    public void actionPerformed(ActionEvent actionEvent) {
    }

}

ИтакПока все работает, и это здорово. Однако, как требование, меня попросили сделать один обработчик кнопок для каждого класса. Может кто-нибудь объяснить мне, что на самом деле здесь делает мой buttonHandler? Мне кажется, что вместо создания анонимных функций и переопределения события actionPerformed я мог бы сделать это лучше (создать событие в классе обработчика кнопок и повлиять на его размер в зависимости от того, какая кнопка нажата). Я не знаю, как это сделать, поэтому любая помощь с объяснением была бы отличной!

Большое спасибо!

Брэндон

Ответы [ 3 ]

0 голосов
/ 27 октября 2019

ButtonHandler1 на самом деле не используется, поскольку передаваемые ему параметры никогда не используются, и его единственный метод переопределяется при его создании. Итак, это:

     butSmall.addActionListener(new ButtonHandler1(this, 200){
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                size = 200;
                panel.repaint();
            }
      });

Может быть написано без построения ButtonHandler1:

    butSmall.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            size = 200;
            panel.repaint();
        }
    });

Или с помощью лямбда-выражения:

    butSmall.addActionListener(actionEvent -> {
        size = 200;
        panel.repaint();
    });

Есть много способовВы можете достичь желаемой функциональности. Основываясь на том, что вы написали, вы можете определить ButtonHandler1 следующим образом:

class ButtonHandler1 implements ActionListener{
    private final FilledFrame theApp;
    private final int theSize;
    ButtonHandler1(FilledFrame app, int size){
        theApp = app;
        theSize = size;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        theApp.size = theSize; //better use a setter in FilledFrame
        theApp.repaint();
    }
}

И использовать его следующим образом:

    butSmall.addActionListener(new ButtonHandler1(this, 200));

    butMedium.addActionListener(new ButtonHandler1(this, 300));

    butLarge.addActionListener(new ButtonHandler1(this, 400));

Создание ButtonHandler1 внутреннего класса в FilledFrameделает вещи проще:

class ButtonHandler1 implements ActionListener{
    private final int theSize;
    ButtonHandler1(int size){
        theSize = size;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        size = theSize;
        repaint();
    }
}

Используйте его по:

    butSmall.addActionListener(new ButtonHandler1(200));

    butMedium.addActionListener(new ButtonHandler1(300));

    butLarge.addActionListener(new ButtonHandler1(400));
0 голосов
/ 27 октября 2019

Я не уверен, что понял вопрос, но есть два способа реорганизовать ваш код:

  1. Удалить полностью ваш класс ButtonHandler1 и реализовать всю логику в анонимном классе:
    //FilledFrame.java

    butSmall.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    FilledFrame.this.size = 200;
                    panel.repaint();
                }
            });

Вы можете добавить несколько методов получения и установки в ваш класс FilledFrame и вызвать их в ButtonHandler1.actionPerformed, чтобы реализовать там логику следующим образом:
    package Lab2;

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    // This is a class whose object will handle the event.
    public class ButtonHandler1 implements ActionListener{
        private FilledFrame theApp;
        private int theSize;
        ButtonHandler1(FilledFrame app, int size){
            theApp = app;
            theSize = size;
        }

        public void actionPerformed(ActionEvent actionEvent) {
            theApp.setSizeMember(200); //do not use theApp.setSize(), create a method with a different name
            theApp.getSquarePanel().repaint();
        }

    }

Я оставляю создание методов получения /устанавливает на FilledFrame вам.

0 голосов
/ 27 октября 2019

Любой обработчик *Listener используется для обработки events, сгенерированного из объекта, который также прослушивается. В основной программе кажется, что у вас есть несколько кнопок, которые изменяют размер окна.

В случае вашего класса, который реализует buttonHandler, вы ничего не делаете, потому что ваш метод actionPerformed неделать что-либо.

И anonymous classes - приемлемый способ реализации слушателей. Однако я предпочитаю использовать inner classes, потому что они более чистые (imho) и все еще имеют доступ к state из enclosing class.

Вот как должен выглядеть ваш класс обработчика:

// This is a class whose object will handle the event.
class ButtonHandler1 implements ActionListener {
   private FilledFrame theApp;
   private int         theSize;

   ButtonHandler1(FilledFrame app, int size) {
      theApp = app;
      theSize = size;
   }

   public void actionPerformed(ActionEvent actionEvent) {
      theApp.size = theSize;
      theApp.repaint();
   }
}

А вот вызовы, которые добавляют этот обработчик к вашим кнопкам.

      butSmall.addActionListener(new ButtonHandler1(this, 200));
      butMedium.addActionListener(new ButtonHandler1(this, 300));
      butLarge.addActionListener(new ButtonHandler1(this, 400));
...