ActionListener между двумя классами
Импорт javax.swing.*;
Метки класса расширяет JFrame {JPanel pnl = new JPanel ();
ImageIcon duke = new ImageIcon("duke.png");
JLabel lbl1 = new JLabel(duke);
JLabel lbl2 = new JLabel("Duke is the friendly mascot of Java technology.");
JLabel lbl3 = new JLabel ("Duke", duke, JLabel.CENTER);
public Labels(){
super("Swing Labels");
setSize(1000 , 800);
setDefaultCloseOperation( EXIT_ON_CLOSE);
add(pnl);
setVisible(true);
lbl1.setToolTipText("Duke - the Java Mascot");
lbl3.setHorizontalTextPosition(JLabel.CENTER);
lbl3.setVerticalTextPosition(JLabel.BOTTOM);
pnl.add(lbl1);
pnl.add(lbl2);
pnl.add(lbl3);
}
public static void main(String [] args){
Labels gui = new Labels();
}
}
Что если я хочу использовать это как JApplet? что должно быть сделано? Это трудно изменить?
Вещи, которые работают на JFrame, такие же, как и в JApplet?
4 ответа
Как я рекомендовал в одном из ваших предыдущих вопросов, вы должны реорганизовать свою программу, чтобы она соответствовала шаблону Model-View-Controller или одному из его вариантов, поскольку это позволит вам четко отделить управляющий код (который вызывается ActionListener) из графического интерфейса. Для примера программы MVC, пожалуйста, проверьте мои предложения и код в этом недавнем ответе.
Некоторый класс, предпочтительно внутренний класс B, если вы собираетесь разрешить ввод только из JPanel B, должен реализовывать ActionListener. Этот ActionListener должен быть добавлен в JTextField:
myInputTextField.addActionListener(theActionListenerIAmGoingToWrite).
Этот ActionListener должен определить actionPerformed() примерно так:
String text = inputTextField.getText();
Integer inputInteger = Integer.getInteger(text).toInt();
graph.doStuffWithIntegerInput(inputInteger);
Вопросы дизайна, на которые нужно ответить:
Является ли ActionListener анонимным внутренним классом? Если вы собираетесь использовать его только с конкретными экземплярами графа и B, которые знают друг о друге, то идите по этому пути. Если это так, он должен получить ссылку на экземпляр Graph из содержащего его класса, что означает, что B имеет такой экземпляр, чтобы предложить его.
Можно ли повторно использовать действие ActionListener в другом месте? Будет ли виджет "вводить цифры" появляться в других местах на других JPanels? Если так, сделайте это отдельным классом. Вам по-прежнему нужна ссылка на график, так что либо граф должен быть параметром constrcutor, и / или иметь метод setGraph, потому что ему нужно как-то узнать об экземпляре графа, чтобы он мог отправить ему сообщение.
сделанный!
редактировать 2
Итак, давайте сопоставим то, что у вас есть, с платформой MVC. Таким образом, ваше представление состоит из класса Graph, вашего класса B и ваших textFields.
Теперь, содержащиеся в вашем классе графиков, у вас также есть данные, которые вы хотите отобразить. Это переменные начала, конца, x, y, которые вы определили. Чтобы быть хорошим гражданином MVC-земли, вы должны вытащить их и поместить их в отдельный объект, поскольку они составляют модель вашего графа. Модель, по сути, представляет собой набор фактов, которые вы хотите представить, независимо от того, как они будут представлены, в то время как представление - это весь код, связанный с рисованием материала на экране.
Таким образом, этот объект модели будет простым объектом данных с геттерами и сеттерами для всех переменных, которые вы определили, и будет передан в объект Graph либо в конструкторе, либо через установщик в объекте Graph.
Создав этот объект GraphData, вы отделили представление, Graph и его модель, объект GraphData.
С более сложным Graph вы фактически указали бы в GraphModel, какой "тип" объекта Graph вы хотите создать, каковы будут имена осей, какую линию вы хотите нарисовать, и тому подобное, но это излишне для что у тебя есть.
Хорошо, теперь у вас есть объекты Graph и GraphData и какой-то способ собрать их вместе.
Теперь давайте посмотрим на ваш класс B. Поскольку это JPanel, представление, по сути, он является агрегатором и представителем содержащихся в нем представлений. Это будут Graph и JTextFields. Таким образом, вы добавляете их как есть, указывая макет.
Таким образом, гипотетический рефакторинг выглядит так:
Создать основную программу. В этом главном создании: JTextFields, ActionListener, JPanel (B), Graph и GraphModel.
Свяжите GraphModel с Graph.
Ассоциировать граф с JPanel.
Свяжите ActionListener с JJtextField
Свяжите JTextField с JPanel
Что касается написания ActionListener, просто сделайте его собственным классом, который проще всего написать и понять. Итак, таким образом:
public class MyTextFieldListener implements ActionListener
{
private Graph graph;
public MyTextFieldListener(Graph graph)
{
this.graph = graph;
}// construtor
public void actionPerformed (ActionEvent ae)
{
String text = ((JTextField)ae.getSource()).getText();
Integer inputInteger = Integer.getInteger().(text).toInt();
graph.doStuffWithIntegerInput(inputInteger);
} // actionPerformed
}// class
Теперь сложность может заключаться в том, что вы не можете обновить график, пока не получите информацию из всех четырех текстовых полей. Есть разные способы изменить этот код, чтобы приспособиться к этому, но это основная идея того, куда вам нужно идти.
НТН
Ну хорошо, сначала проверьте это: слушатель действия в другом классе - Java
Теперь все, что вам нужно сделать, это отредактировать его в соответствии с вашими потребностями, и в actionPerformed(ActionEvent ae)
Затем вы получите значения в классе controlB.java, получив доступ к данным с помощью метода accessor / get или заставив класс Actionlistener расширить элемент ControlB, чтобы он имел доступ ко всем его общедоступным данным, а затем, как только вы получите значения, передайте их Graph.java или во время инициации или с помощью метода мутатора / набора?
ХОРОШО. Давайте поговорим о вашем объекте RangeXY. Какова его цель? Я спрашиваю, потому что, кажется, не нужно ничего из JTextFields, то есть из пользовательского ввода.
Когда вы вызываете graph.doStuffWithIntegerInput(), на самом деле вы не используете целочисленный ввод от пользователя, который поступает из текстового поля. Вы используете (и это просто неправильно) int, который вы передали в конструктор RangeXY. Затем вы (и здесь идет "просто неправильная" часть) передаете это int статическому методу Integer getInteger(). На самом деле, это не скомпилируется, поскольку getInteger принимает строку и превращает ее в целое число.
Хорошо, так что давайте просто сделаем это. Делай одну вещь за раз. Сначала напишите класс, который подходит под это описание:
Он реализует ActionListener; У него есть переменная-член для Graph; Переменная-член для Graph задается либо в установщике, либо передается в конструктор. У него ПУСТОЙ метод actionPerformed (на данный момент)
Просто сделай это, и мы возьмем это оттуда.