JButton not responsive - have to click twice - java

I created a GUI using java swing and in a specific situation, the JButton is unresponsive and I have to click it twice. On the click, it takes the info in the textArea and sends it to a TextParser class to be parsed. If I type more stuff in the area after, and click the evaluateButton, it doesn't respond and I have to click it again to work. Does anyone know if this is a known bug or how I can fix this?
The code for the class is as follows.
/**
* Add the components to the GUI.
* #param pane - the pane for the GUI
*/
public static void addComponentsToPane(Container pane) {
pane.setLayout(new BorderLayout());
JPanel instructionsPanel = new JPanel();
JLabel instructions = new JLabel("Enter the email text below");
instructionsPanel.setBackground(Color.LIGHT_GRAY);
instructionsPanel.add(instructions);
pane.add(instructionsPanel, BorderLayout.NORTH);
JPanel textAreaPanel = new JPanel();
textAreaPanel.setBackground(Color.LIGHT_GRAY);
final JTextArea textArea = new JTextArea();
textArea.setBackground(Color.WHITE);
textArea.setMinimumSize(new Dimension(400,350));
textArea.setMaximumSize(new Dimension(400,350));
textArea.setPreferredSize(new Dimension(400,350));
textArea.setLineWrap(true);
Border border = BorderFactory.createLineBorder(Color.BLACK);
textArea.setBorder(border);
textArea.setMinimumSize(new Dimension(500, 200));
textArea.setFont(new Font("Serif", Font.PLAIN, 16));
textAreaPanel.add(textArea);
pane.add(textAreaPanel, BorderLayout.CENTER);
JPanel scoringPanel = new JPanel();
JButton evaluateButton = new JButton("Evaluate Email");
final JLabel scoreLabel = new JLabel("");
JButton uploadFileBtn = new JButton("Upload File");
JButton importTermsBtn = new JButton("Import Terms");
scoringPanel.add(evaluateButton);
scoringPanel.add(uploadFileBtn);
scoringPanel.add(importTermsBtn);
scoringPanel.add(scoreLabel);
pane.add(scoringPanel, BorderLayout.SOUTH);
evaluateButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
try {
String email = textArea.getText();
TextParser textParser = new TextParser(email);
double score = textParser.parse();
scoreLabel.setText(score+"");
} catch (Exception ex) {
System.out.println(ex);
}
}
});
uploadFileBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
scoreLabel.setText("Feature not yet available.");
}
});
importTermsBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
DatabaseInput d = new DatabaseInput();
d.main(null);
}
});
}
/**
* Create the GUI and show it.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("EmailGUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setLocationRelativeTo(null);
frame.setPreferredSize(new Dimension(500,500));
frame.setTitle("Email Text Input");
frame.setResizable(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(screenSize.width, screenSize.height);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
My main method just calls createAndShowGUI(). I am new to StackOverflow so if I need to give more or less information in my post please let me know!

As Reimeus and Jason C said in the comments, I should have been using ActionListener which works perfectly.

Related

Adding a JScrollPane to an existing JPanel

I am trying to add a JScrollPane (createTeamScrollPane) to a JPanel (createTeamPanel) that I have. I have a frame, with a BorderLayout with the NORTH portion being used by a JPanel called tabMenu, and then the CENTER portion I would like my 'createTeamPanel' to have this scrolling ability as it will have more content than what I can fit on the screen at once. I am then adding both panels to the frame. Currently the code as is runs but the window appears blank. Once resizing the window, I then see the 3 buttons in the NORTH portion of my frame (why is this happening?) and when I click on 'Create Team' it brings up the list of JLabels and JButtons I expect but I don't see any scrolling bars?
public static void main (String args[]) {
JFrame frame = new JFrame();
frame.setTitle("v0.01");
frame.setSize(800, 800);
//frame.setLayout(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel tabMenu = new JPanel();
JPanel createTeamPanel = new JPanel();
createTeamPanel.setLayout(new BoxLayout(createTeamPanel, BoxLayout.Y_AXIS));
createTeamPanel.setSize(800, 700);
createTeamPanel.setVisible(showCreateTeamPanel);
createTeamPanel.setBackground(Color.gray);
JScrollPane createTeamScrollPane = new JScrollPane(createTeamPanel);
createTeamScrollPane.setBounds(50, 50, 200, 500);
createTeamScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
createTeamScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
createTeamScrollPane.setPreferredSize(new Dimension(500,500));
//createTeamPanel.add(createTeamScrollPane);
List<Player> teamList = MockTeams.initTeam();
int xcoord = 100;
int ycoord = 50;
for(Player player : teamList) {
JLabel label = new JLabel(player.getName());
label.setBounds(xcoord, ycoord, Constants.buttonWidth, Constants.buttonHeight);
JButton addToTeamBtn = new JButton("Add to team");
addToTeamBtn.setBounds(xcoord + 100, ycoord, Constants.buttonWidth, Constants.buttonHeight);
addToTeamBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
myTeam.add(player);
addToTeamBtn.setEnabled(false);
}
});
createTeamPanel.add(label);
//createTeamFrame.add(label);
createTeamPanel.add(addToTeamBtn);
//createTeamFrame.add(addToTeamBtn);
ycoord += 50;
}
JButton createTeamBtn = new JButton("Create Team");
createTeamBtn.setBounds(0,0,150,20);
createTeamBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Hide/Show Create team panel
if (!showCreateTeamPanel) {
showCreateTeamPanel = true;
createTeamPanel.setVisible(showCreateTeamPanel);
} else {
showCreateTeamPanel = false;
createTeamPanel.setVisible(showCreateTeamPanel);
}
}
});
JButton manageTeamBtn = new JButton("Team Statistics");
manageTeamBtn.setBounds(100,150,150,40);
JButton resetBtn = new JButton("Reset Season");
resetBtn.setBounds(100,200,150,40);
tabMenu.add(createTeamBtn);
tabMenu.add(manageTeamBtn);
tabMenu.add(resetBtn);
mainPanel.add(tabMenu, BorderLayout.NORTH);
mainPanel.add(createTeamPanel, BorderLayout.CENTER);
frame.add(mainPanel);
}
Expected result is to see a scrolling ability on the createTeamPanel but it is not there.
Fixed: I was able to add the JScrollPane to the mainPanel with:
mainPanel.add(createTeamScrollPane, BorderLayout.CENTER);

Can't set background color

For some reason my background just doesn't turn blue. Does anyone know how to solve this with keeping everything inside?
I've been trying to fix this for ages already, but nothing works apparantly..
public static void window() {
JFrame frame = new JFrame("Sharp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(
new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
JPanel b = new JPanel();
JLabel label2 = new JLabel("Hello, World!", JLabel.CENTER);
label2.setAlignmentY(0);
label2.setAlignmentX(0);
label2.setText("<html>Made by Julian</html>");
JPanel a = new JPanel();
b.add(label2);
a.setAlignmentX(Component.CENTER_ALIGNMENT);
a.setPreferredSize(new Dimension(850, 500));
a.setMaximumSize(new Dimension(850, 850)); // set max = pref
JToggleButton tb = new JToggleButton("SHARP Instructions");
tb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JToggleButton btn = (JToggleButton) e.getSource();
if(btn.isSelected()) {
Desktop d = Desktop.getDesktop();
try {
d.browse(new URI("https://pastebin.com/nDdGZ0cJ"));
} catch (IOException | URISyntaxException e2) {
e2.printStackTrace();
}
}
}
});
frame.setBackground(Color.BLUE);
a.add(tb);
// JPanel b = new JPanel();
frame.add(a, new GridBagConstraints());
frame.getContentPane().add(a);
frame.getContentPane().add(b);
//frame.getContentPane().add(b);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
Your JPanel a is on top of your JFrame, so just:
a.setBackground(Color.BLUE); will fix it.

Java Swing Components Drawing Over Multiple Panels

I'm having an issue that I've been trying to solve all day. I have two panels inside a frame and in one panel I've added components. The components, however, seem to have an equal hierarchy value as the panel and as such treat the Frame as the parent instead, ignoring where the panels are located. Basically the components are added to one panel but display on top of both across the whole frame. (Unfortunately I can't post a picture at this time, please up vote the question to allow me to if needed). What is causing this and how can I fix it?
The relevant code:
JFrame arranFrame = new JFrame("Edit Arrangement");
arranFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel grid = new JPanel();
JPanel tools = new JPanel();
grid.setSize(700, 600);
tools.setSize(200, 600);
JLabel widthLabel = new JLabel("Width");
JLabel depthLabel = new JLabel("Depth");
JLabel columnLabel = new JLabel("Columns");
final JTextField rowWidthInput = new JTextField(30);
final JTextField rowsInput = new JTextField(30);
final JTextField columnInput = new JTextField(30);
rowWidthInput.setSize(40, 30);
rowsInput.setSize(40, 30);
columnInput.setSize(40, 30);
rowWidthInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartWidth = Integer.parseInt(rowWidthInput.getText());
}
});
rowsInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartRows = Integer.parseInt(rowsInput.getText());
}
});
columnInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartColumns = Integer.parseInt(columnInput.getText());
}
});
//Enter button for grid modifying creation and setup
JButton enterButton = new JButton("Enter");
enterButton.setSize(180, 50);
enterButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
chartWidth = Integer.parseInt(rowWidthInput.getText());
chartRows = Integer.parseInt(rowsInput.getText());
chartColumns = Integer.parseInt(columnInput.getText());
}
});
//Save Arrangement button creation and setup
JButton saveButton = new JButton("Save Arrangement");
saveButton.setSize(180, 50);
saveButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SaveArrangement(userDocuments + "\\TSA Seating Chart\\Arrangements\\Period" + period + ".txt");
}
});
tools.setBackground(Color.RED); //Temp for visualization where the panes are
tools.add(widthLabel);
tools.add(rowWidthInput);
tools.add(depthLabel);
tools.add(rowsInput);
tools.add(columnLabel);
tools.add(columnInput);
tools.add(enterButton);
tools.add(saveButton);
arranFrame.getContentPane().add(grid);
arranFrame.getContentPane().add(tools);
//Finalize the GUI
arranFrame.pack(); //Pack all the content together
arranFrame.setSize(900, 600); //Set the size of the window
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
arranFrame.setLocation(dim.width/2-arranFrame.getSize().width/2, dim.height/2-arranFrame.getSize().height/2);
arranFrame.setVisible(true); //Display the seatingFrame

Adding ActionListeners to JPanel

This questions has been asked a few times but mine is a little different. I created a small application and in the view I added a few JPanels to a JFrame. I then try to add actionListeners in the controller which is where the problem happened.
The code below gives me the following error:
The method addActionListener(new ActionListener(){})
is undefined for the type JPanel
The view class
public class MainMenuGUI {
JTabbedPane tabbedPane = new JTabbedPane();
JPanel findUserPanel;
JPanel deleteUserPanel;
JPanel addUserPanel;
JFrame frame = new JFrame();
JPanel tabbedPanel = new JPanel();
//Controller class for tabbedPanel
ControllerTabbedPane listen = new ControllerTabbedPane(this);
//Controller class for findUserPanel
FindUserPanelController findUserController = new FindUserPanelController(findUserPanel);
public MainMenuGUI() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
findUserPanel = createFindUserPanel();
deleteUserPanel = createDeleteUserPanel();
addUserPanel = createAddUserPanel();
tabbedPane.addTab("Find User", findUserPanel);
tabbedPane.addTab("Delete User", deleteUserPanel);
tabbedPane.addTab("Add User", addUserPanel);
tabbedPanel.add(tabbedPane);
frame.add(tabbedPanel);
frame.pack();
// opens frame in the center of the screen
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
JPanel createFindUserPanel() {
findUserPanel = new JPanel();
findUserPanel.setPreferredSize(new Dimension(300, 300));
findUserPanel.setLayout(new GridLayout(5, 7));
JLabel firstlbl = new JLabel("First Name");
JLabel lastlbl = new JLabel("Last Name");
JLabel addresslbl = new JLabel("Address");
JLabel agelbl = new JLabel("Age");
JTextField firstNametxt = new JTextField(15);
JTextField lastNametxt = new JTextField(15);
JTextField addresstxt = new JTextField(30);
JTextField age = new JTextField(3);
JButton btn = new JButton("Submit");
JScrollPane window = new JScrollPane();
window.setViewportBorder(new LineBorder(Color.RED));
window.setPreferredSize(new Dimension(150, 150));
findUserPanel.add(firstlbl);
findUserPanel.add(firstNametxt);
findUserPanel.add(lastlbl);
findUserPanel.add(lastNametxt);
findUserPanel.add(addresslbl);
findUserPanel.add(addresstxt);
findUserPanel.add(agelbl);
findUserPanel.add(age);
findUserPanel.add(window, BorderLayout.CENTER);
findUserPanel.add(btn);
return findUserPanel;
}
Controller Class
public class ControllerTabbedPane {
MainMenuGUI mainMenuGUI;
int currentTabbedIndex = 0;
ControllerTabbedPane(MainMenuGUI mainMenuGUI){
this.mainMenuGUI = mainMenuGUI;
addTabbedPaneListeners();
}
private void addTabbedPaneListeners() {
mainMenuGUI.tabbedPane.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent ce) {
currentTabbedIndex = mainMenuGUI.tabbedPane.getSelectedIndex();
System.out.println("Current tab is:" + currentTabbedIndex);
}
});
}
/*ERROR saying The method addActionListener(new ActionListener(){})
is undefined for the type JPanel*/
private void findPanelListeners() {
mainMenuGUI.findUserPanel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
});
}
This is the way to achieve your request:
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JButton bt1 = new JButton();
JButton bt2 = new JButton();
panel1.add(bt1);
panel2.add(bt2);
bt1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Bt1 on panel1 pressed");
}
});
bt2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Bt2 on panel2 pressed");
}
});
You can modify variables or other objects into the listeners to store which panel was "pressed".
I think its not possible to add addActionListner() to JPanel
Instead
You can use,
JPanel p1=new JPanel();
p1.addMouseListener(this);
And override
public void mouseClicked(MouseEvent me)
{
int x=me.getX();
int y=me.getY();
System.out.println(x+","+y);
//By using x AND y you can identify the panel
}
NB: extends MouseAdapter

How to get Current JPanel from Button Click

On the event of clicking a button how would I get the JPanel it is in currently?
I know how to make a button and add an actionlistener and do event handling. I don't know how to select the current panel.
The code from the post above modified to avoid using final variables
public void buildUI() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Button");
panel.add(button);
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("The current panel is " + ((JButton)e.getComponent()).getParent());
}
});
frame.add(panel);
frame.pack();
frame.setDefaultCloseBehavior(JFrame.CLOSE_ON_EXIT);
frame.setVisible(true);
}
public void buildUI() {
JFrame frame = new JFrame();
final JPanel panel = new JPanel();
JButton button = new JButton("Button");
panel.add(button);
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("The current panel is " + panel);
}
});
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
EDIT: Adding example where listener code is not in the same class as GUI code.
//PanelPrintingListener.java
public class PanelPrintingListener implements ActionListener {
private JPanel panel;
public PanelPrintingListener(JPanel panel) {
this.panel = panel;
}
public void actionPerformed(ActionEvent e) {
System.out.println("The current panel is " + panel);
}
}
//OtherFoo.java
public void buildUI() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Button");
panel.add(button);
button.addActionListener( new PanelPrintingListener(panel) );
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
If you are looking for the panel that is currently active (meaning that it is the top one in the stack), then you can use the getComponent() method.
Component active = parentPanel.getComponent(0);
Now the "active" object will have the currently active or displayed panel.Note that "parentPanel" is the panel on which the required sub-panels are placed.

Categories