variabel kelas tidak diperbarui setelah pemanggilan metode
Saya cukup baru mengenal Java dan hanya setelah meneliti dan googling dan membaca banyak jawaban, saya memposting ini. Saya agak tersesat. Sedikit panduan akan sangat membantu. Berikut ini adalah metode dari kelas yang mengimplementasikan antarmuka "ActionListener". Apa yang saya coba lakukan adalah ini: Ada tombol yang diklik harus membuka jendela baru dengan dua opsi dalam bentuk dua Tombol Radio. Saya perlu mengetahui Tombol Radio yang dipilih untuk digunakan lebih lanjut dalam kode saya. Saya menyatakan, variabel "scoreOption" sebagai variabel kelas dan statis, dan kemudian mencoba untuk memperbaruinya dalam metode abstrak "actionPerformed". Tetapi ketika saya merujuknya (setelah pemanggilan metode), nilainya tetap sama - null, atau apa pun yang saya setel awalnya. Ini kodenya:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class StartEvents implements ActionListener {
StartPanel startingPanel;
static String scoreOption;
public StartEvents(StartPanel startPanel) {
startingPanel = startPanel;
}
// Scoring System Window - 1
public void scoringSystem() {
startingPanel.scoringSystem.addActionListener(new ActionListener () {
@Override
public void actionPerformed(ActionEvent e) {
Panel scoringSystemPanel = new Panel();
JFrame scoreSystemFrame = scoringSystemPanel.frame(150, 250, "Scoring System", 2, true);
JPanel scoreSystemPanel = scoringSystemPanel.panel(Color.lightGray);
JButton confirmSelection = scoringSystemPanel.button(40, 20, "Confirm");
JRadioButton scoreSystem1 = scoringSystemPanel.radioButton("Option 1: Same Points Per Hit");
scoreSystem1.setActionCommand("Option 1");
JRadioButton scoreSystem2 = scoringSystemPanel.radioButton("Option 2: Unique Points Per Hit");
scoreSystem2.setActionCommand("Option 2");
ButtonGroup scoreSys = new ButtonGroup();
scoreSys.add(scoreSystem1);
scoreSys.add(scoreSystem2);
scoreSystemFrame.getContentPane().add(scoreSystemPanel);
scoreSystemPanel.add(scoreSystem1);
scoreSystemPanel.add(scoreSystem2);
scoreSystemPanel.add(confirmSelection);
// Get Selection Event
// Option 1
scoreSystem1.addActionListener(new ActionListener () {
@Override
public void actionPerformed(ActionEvent e) {
if (scoreSystem1.isSelected()) {
scoreOption = scoreSystem1.getActionCommand();
}
}
});
// Option 2
scoreSystem2.addActionListener(new ActionListener () {
@Override
public void actionPerformed(ActionEvent e) {
if (scoreSystem2.isSelected()) {
scoreOption = scoreSystem2.getActionCommand();
}
}
});
// Confirm Event
confirmSelection.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
scoreSystemFrame.dispose();
}
});
}
});
}
Kelas Game Utama tempat sistem penilaian metode dipanggil.
import java.util.ArrayList;
public class Game {
public static void main(String[] args) {
StartPanel startingPanel = new StartPanel();
startingPanel.makeStartPanel();
StartEvents starter = new StartEvents(startingPanel);
starter.rulesButton();
starter.exitButton();
starter.highScoresButton();
ArrayList<Integer> dimensions = starter.boardSizeSelector();
// Problem Zone
System.out.println(StartEvents.scoreOption);
starter.scoringSystem();
System.out.println(StartEvents.scoreOption);
// The two values of scoreOption should be different
String[] playPanelDetails = {"970", "Player 1", "450"};
// Final Start of the Game
starter.startGameButton(playPanelDetails, dimensions);
}
}
Lebih lanjut, dapatkah Anda memberi tahu saya terkait pertanyaan berikut:
- Direkomendasikan untuk menerapkan "ActionListener" dalam "ActionListener" lain? Praktik yang Baik?
- Bisakah hanya ada satu deklarasi metode "actionPerformed" atau dapatkah itu juga dibebani?
- Apakah mungkin mendapatkan nilai kembali dari metode "actionPerformed"?
Saya akan sangat berterima kasih jika beberapa petunjuk dapat diberikan. Saya benar-benar mencoba banyak dan baru kemudian mempostingnya di sini. Terima kasih banyak sebelumnya.
Edit Kecil: Ketika saya "System.out.println" di "perintah tindakan" di sana, ia bekerja dengan sempurna, mencetak di konsol. Tetapi tidak ketika saya mencoba untuk memperbarui variabel kelas dan kemudian mencoba untuk mencetaknya setelah pemanggilan metode. Entah apakah ini membantu.
Jawaban
JFrame bukanlah modal - Anda membuatnya dan menampilkannya, itu tidak memblokir aliran kode, dan Anda mengekstrak nilai scoreOption tepat saat JFrame sedang ditampilkan dan sebelum pengguna memiliki kesempatan untuk mengubahnya. Anda perlu menggunakan dialog modal seperti JDialog yang dibuat sebagai dialog modal atau menggunakan JOptionPane (yang sebenarnya hanyalah modal JDialog di bawah kap). Ini akan memblokir aliran kode sehingga Anda mengekstrak data hanya setelah diubah oleh pengguna.
Contoh yang membuktikan maksudnya:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooGui01 extends JPanel {
private String frameTest = "";
private String dialogTest = "";
private JFrame mainFrame = new JFrame("Main GUI");
private JFrame subFrame;
private JDialog dialog;
public FooGui01() {
JButton showFrameBtn = new JButton("Show JFrame");
showFrameBtn.addActionListener(e -> {
changeTest1WithJFrame();
System.out.println("frameTest: " + frameTest);
});
JButton showDialogBtn = new JButton("Show JDialog");
showDialogBtn.addActionListener(e -> {
changeTest2WithModalDialog();
System.out.println("dialogTest: " + dialogTest);
});
JPanel panel = new JPanel();
panel.add(showDialogBtn);
panel.add(showFrameBtn);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(panel);
mainFrame.pack();
mainFrame.setLocationByPlatform(true);
mainFrame.setVisible(true);
}
public void changeTest1WithJFrame() {
if (subFrame == null) {
subFrame = new JFrame("Frame");
JButton button = new JButton("Press me");
button.addActionListener(e -> {
frameTest = "Hello World and frameTest";
subFrame.setVisible(false);
});
JPanel panel = new JPanel();
panel.add(button);
subFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
subFrame.add(panel);
subFrame.pack();
subFrame.setLocationByPlatform(true);
}
subFrame.setVisible(true);
}
public void changeTest2WithModalDialog() {
if (dialog == null) {
dialog = new JDialog(mainFrame, "Dialog", Dialog.ModalityType.APPLICATION_MODAL);
JButton button = new JButton("Press me");
button.addActionListener(e -> {
dialogTest = "Hello World and dialogTest";
dialog.setVisible(false);
});
JPanel panel = new JPanel();
panel.add(button);
dialog.add(panel);
dialog.pack();
dialog.setLocationByPlatform(true);
}
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new FooGui01());
}
}
Jika Anda menjalankan kode, saat Anda menampilkan sub JFrame, teks pengujian segera ditampilkan di konsol sebelum dialog ditangani. Jika Anda menekan tombol untuk menampilkan dialog, tampilan teks percobaan akan ditunda sampai tombol telah ditekan, mengubah teks.
Menekan tombol bingkai dua kali pada akhirnya akan menampilkan teks yang benar sejak teks tersebut diatur saat pertama kali ditampilkan.
JDialig sama seperti JFrame. Yaitu Anda menambahkan komponen ke dalamnya seperti Anda melakukan bingkai apa pun.
Perbedaannya adalah Anda dapat membuat modal JDialog. Artinya saat Anda menggunakan:
dialog.setVisible(true);
System.out.println("here");
Kode setelah pernyataan setVisible (...) tidak akan dijalankan sampai dialog ditutup. Ini juga berarti Anda tidak dapat mengklik JFrame induk hingga dialog ditutup.
Cara mudah untuk membuat file modal JDialog
adalah dengan menggunakan file JOptionPane
. Ini memiliki beberapa metode standar yang membuat prompt untuk input pengguna menjadi mudah.
Misalnya dalam kasus Anda, Anda dapat melakukan sesuatu seperti:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
private int scoringOption = -1;
public SSCCE()
{
JButton button = new JButton("Change Points Option");
add(button);
button.addActionListener((e) -> displayOptionDialog());
}
private void displayOptionDialog()
{
Window window = SwingUtilities.windowForComponent( this );
// Custom button text
Object[] options = {"Option 1: Same Points Per Hit", "Option 2: Unique Points Per Hit"};
scoringOption = JOptionPane.showOptionDialog(
window,
"Select your scoring option:",
"Scoring Option",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
null);
System.out.println( scoringOption );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
Di atas juga merupakan contoh dari "MRE". Kode ini sederhana dan terdapat dalam satu kelas yang dapat Anda salin / tempel / kompilasi dan uji.
Baca bagian dari tutorial Ayunan tentang Cara Menggunakan Dialog untuk lebih banyak contoh penggunaan a JOptionPane
.
Jika Anda benar-benar ingin menggunakan tombol radio, Anda dapat membuat panel dengan tombol radio dan menampilkannya di panel opsi menggunakan showConfirmDialog(...)
metode ini. Saat dialog ditutup, Anda perlu mendapatkan perintah tindakan dari ButtonModel
dari ButtonGroup
.
Lihat: cara menyetel & mengelola tata letak JOptionPane untuk contoh dasar pendekatan ini untuk Anda mulai.