#java #button #awt
Вопрос:
Я довольно новичок в кодировании и столкнулся с этой проблемой в своем коде. Я создаю кнопку с помощью импорта Java AWT. Затем я проверяю ответ с помощью цикла while и хочу создать другую кнопку после, однако .add (), похоже, больше не работает.
import java.awt.*;
import java.awt.event.*;
public class Main1
{
public static void main(String[] args)
{
Frame f = new Frame();
f.setSize(500, 500);
f.setVisible(true);
ButtonPanel bp = new ButtonPanel(f);
bp.x = null;
while (bp.x == null)
{
}
System.out.println(bp.x);
//THE ISSUE- THIS WILL NOT APPEAR AFTER BUTTON PRESS
f.add("South", new Button("REEE"));
}
}
class ButtonPanel extends Panel implements ActionListener
{
volatile String x;
public ButtonPanel(Frame f)
{
Button b = new Button("Hi");
b.addActionListener(this);
f.add("North", b);
}
public void actionPerformed(ActionEvent e)
{
x = e.getActionCommand();
}
}
Я пробовал решения для этого в течение последнего дня или около того, и, похоже, ничего не работает. Я видел в других сообщениях, что люди говорили использовать Wait/Notify, однако я не слишком уверен, как это работает, и я хотел бы четко знать, что происходит не так в моей программе (хотя я все еще открыт для использования Wait/Notify в своем решении).
Любая помощь будет признательна, большое вам спасибо
Комментарии:
1. О да, извините, я кое-что проверял, хотел удалить это для этого вот
2. Не используйте
while
цикл для «остановки» выполнения кода подобным образом. Вместо этого используйте обратный вызов (наблюдатель)3. Убедительное предложение: не используйте AWT. После AWT существует два поколения графических фреймворков: Swing и JavaFX. Если вы хотите узнать что-то новое, попробуйте javafx.
Ответ №1:
Итак, здесь речь идет о ряде проблем.
Во — первых, это тот факт, что менеджеры по верстке, как правило, ленивы. Это означает, что вы можете быстро добавить и/или удалить несколько компонентов, а затем выполнить один макет и покраску.
Для этого вам нужно revalidate
Container
, чтобы приложение было обновлено.
Далее, AWT (и расширение Swing) основаны на концепции «Модель-представление-контроллер», одним из аспектов которой является «шаблон наблюдателя». Это в основном концепция обратного вызова, которая позволяет вам получать уведомления, когда происходит что-то интересное.
Button
использует an ActionListener
для генерации событий, когда кнопка «активирована». Это и есть «модель наблюдателя» в действии.
Почему это так важно? Вы действительно хотите подумать о том, какая информация необходима для передачи куда и кто на самом деле несет ответственность за то, что делает.
Например, действительно ButtonPanel
ли это ответственность за обновление кадра? Действительно ли предоставление ButtonPanel
неограниченного контроля над кадром-хорошая идея?
Вместо ButtonPanel
этого «должно» предоставлять какое-то уведомление, когда произошло какое-то действие, и тогда любые заинтересованные стороны должны иметь возможность делать все, что им нужно.
В качестве «базового» примера…
import java.awt.Button;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventListener;
import javax.swing.event.EventListenerList;
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
public Test() {
Frame f = new Frame();
f.setPreferredSize(new Dimension(500, 500));
f.pack();
ButtonPanel bp = new ButtonPanel(f);
bp.addObsever(new Observer() {
@Override
public void hiWasPerformed() {
f.add("South", new Button("REEE"));
f.revalidate();
}
});
f.setVisible(true);
}
public interface Observer extends EventListener {
public void hiWasPerformed();
}
class ButtonPanel extends Panel {
private EventListenerList eventListener = new EventListenerList();
public ButtonPanel(Frame f) {
Button b = new Button("Hi");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Observer[] listeners = eventListener.getListeners(Observer.class);
for (Observer observer : listeners) {
observer.hiWasPerformed();
}
}
});
f.add("North", b);
}
public void addObsever(Observer observer) {
eventListener.add(Observer.class, observer);
}
public void removeObsever(Observer observer) {
eventListener.remove(Observer.class, observer);
}
}
}
Ответ №2:
Похоже, что ничего не происходит, потому что кнопки добавляются ниже нижней части окна. Вам следует рассмотреть возможность использования менеджера компоновки для решения этой проблемы.
Однако в то же время простое решение состоит в том, чтобы переместить эту строку f.add("South", new Button("REEE"));
внутри события действия и использовать Frame.pack();
:
public class Main1
{
public static void main(String[] args)
{
Frame f = new Frame();
//set minimums rather than a fixed size
f.setMinimumSize(new Dimension(500, 500));
f.setVisible(true);
CustomButton b = new CustomButton(f);
//Add this line to update/size/show the UI
f.pack();
//Don't place any more code inside the main method. Future events should be triggered by interacting with the UI/buttons
}
}
Тогда для кнопки нам не нужно расширять панель, мы можем сделать что-то вроде этого:
class CustomButton implements ActionListener
{
Frame parentFrame;
public CustomButton(Frame f)
{
parentFrame = f;
Button b = new Button("Hi");
b.addActionListener(this);
f.add("North", b);
}
public void actionPerformed(ActionEvent e)
{
//Add button here instead of the main class
parentFrame.add("South", new Button("REEE"));
//The buttons are being added below the bottom of your window, this will force them to be shown.
//Using a layout manager will solve this ploblem and you will not need to do this:
parentFrame.pack();
}
}
Примечание: при многократном нажатии на кнопку «Привет» появятся интересные результаты, если кнопки «REEE» будут перекрываться или делать странные вещи, если вы измените размер окна.
Комментарии:
1. ОООО, иногда я такая идиотка, я понятия не имела, что это будет создано вне рамок, спасибо
2. Вместо того , чтобы использовать
pack
, что может повлиять на размер окна, если пользователь изменит его, лучше повторно проверить контейнер, содержащий кнопки