I am currently trying to implement an action listener to my JCheckBox so that when it is selected, it will open a JFileChooser for the user to pick a file they want the GUI to use. For starters how would I get the console to print out "Box clicked!" when a user checks the box?
It has been a while since I've programmed in Swing so any advice helps!
public class RadioPanel extends JPanel implements ActionListener
{
private static final long serialVersionUID = -1890379016551779953L;
private JCheckBox box;
private JLabel label;
public RadioPanel(String message)
{
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.WEST;
c.gridx = 0;
c.gridy = 0;
box = new JCheckBox();
this.add(box,c);
c.gridx = 1;
c.gridy = 0;
label = new JLabel(message);
this.add(label, c);
}
I think it's because the code does not have an event listener.
See my code below.
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class RadioPanel extends JPanel implements ActionListener {
private static final long serialVersionUID = -1890379016551779953L;
private JCheckBox box;
private JLabel label;
public RadioPanel(String message) {
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.WEST;
c.gridx = 0;
c.gridy = 0;
box = new JCheckBox();
// here
box.addActionListener(event -> {
JCheckBox checkBox = (JCheckBox) event.getSource();
if (checkBox.isSelected()) {
System.out.println("Box clicked!");
}
});
this.add(box, c);
c.gridx = 1;
c.gridy = 0;
label = new JLabel(message);
this.add(label, c);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
boolean selected = abstractButton.getModel().isSelected();
System.out.println("Is selected :" + selected);
}
};
box.addActionListener(actionListener);
Related
This question already has answers here:
How to Remove an icon on a JButton?
(3 answers)
Closed 5 years ago.
I am working on the Tic Tac application all things are set but the only problem is that I am using images on the Button and I want to make a restart button when this restart Button pressed I want that all the images on the Button should be removed. I have also tried to setIcon(null) but when the Restart button press image is removed and one another problem arises is that Button's get disabled and I am not able to play again.
Is there is any other methods available to remove the icon from the Button?
The OP issue is more than setIcon(null), so I am giving this reply,
Try below source code, but there is a good multi pane scenario for you:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/*
* Used resources within this class or illustration done within is just for the
* study purpose.
*/
public class ImageExample extends JFrame {
private static final long serialVersionUID = 1L;
/*
* used fixed images resource, you can take all directory resources as per your
* need
*/
private String[] leopard = new String[] { "leopard0", "leopard1", "leopard2", "leopard3" };
private URL url;
private JLabel label1, label2, label3, label4;
private ArrayList<Integer> index = new ArrayList<Integer>();
public ImageExample() {
init();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ImageExample();
}
});
}
private void init() {
setTitle("Add And Remove Image");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
setBounds(400, 150, 625, 400);
for (int i = 0; i < leopard.length; i++)
index.add(i);
GridBagConstraints c = new GridBagConstraints();
JPanel panel = new JPanel(); // 1
panel.add(label1 = new JLabel(getIndexIcon(index.get(0))));
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
c.gridheight = 1;
add(panel, c);
panel = new JPanel(); // 2
panel.add(label2 = new JLabel(getIndexIcon(index.get(1))));
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.0;
c.gridx = 1;
c.gridy = 0;
c.gridheight = 1;
add(panel, c);
panel = new JPanel(); // 3
panel.add(label3 = new JLabel(getIndexIcon(index.get(2))));
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 0.0;
c.gridx = 0;
c.gridy = 1;
c.gridheight = 1;
add(panel, c);
panel = new JPanel(); // 4
panel.add(label4 = new JLabel(getIndexIcon(index.get(3))));
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.0;
c.weighty = 0.0;
c.gridx = 1;
c.gridy = 1;
c.gridheight = 1;
add(panel, c);
panel = new JPanel(); // contains JButtons
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.0;
c.gridwidth = 2;
c.gridx = 0;
c.gridy = 2;
add(panel, c);
final JButton prev = new JButton("Previous");
final JButton addImage = new JButton("Add Image");
final JButton removeImage = new JButton("Remove Image");
final JButton next = new JButton("Next");
addImage.setEnabled(false);
panel.add(prev);
panel.add(addImage);
panel.add(removeImage);
panel.add(next);
prev.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
revalidateLabel(label1, revalidateIndex(0, index.get(0) - 1));
revalidateLabel(label2, revalidateIndex(1, index.get(1) - 1));
revalidateLabel(label3, revalidateIndex(2, index.get(2) - 1));
revalidateLabel(label4, revalidateIndex(3, index.get(3) - 1));
}
});
addImage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
revalidateLabel(label1, index.get(0));
revalidateLabel(label2, index.get(1));
revalidateLabel(label3, index.get(2));
revalidateLabel(label4, index.get(3));
addImage.setEnabled(false);
removeImage.setEnabled(true);
prev.setEnabled(true);
next.setEnabled(true);
removeImage.requestFocus();
}
});
removeImage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
removeLabelImage(label1);
removeLabelImage(label2);
removeLabelImage(label3);
removeLabelImage(label4);
prev.setEnabled(false);
next.setEnabled(false);
removeImage.setEnabled(false);
addImage.setEnabled(true);
addImage.requestFocus();
}
});
next.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
revalidateLabel(label1, revalidateIndex(0, index.get(0) + 1));
revalidateLabel(label2, revalidateIndex(1, index.get(1) + 1));
revalidateLabel(label3, revalidateIndex(2, index.get(2) + 1));
revalidateLabel(label4, revalidateIndex(3, index.get(3) + 1));
}
});
setVisible(true);
}
private ImageIcon getIndexIcon(int indexAt) {
if (indexAt < 0)
indexAt = leopard.length - 1;
if (indexAt > (leopard.length - 1))
indexAt = 0;
url = ImageExample.class.getResource("/resources/leopard" + indexAt + ".jpg");
ImageIcon icon = new ImageIcon(url.getPath());
return icon;
}
private void revalidateLabel(JLabel label, int indexAt) {
label.setIcon(getIndexIcon(indexAt));
label.revalidate();
}
private void removeLabelImage(JLabel label) {
label.setIcon(null);
label.revalidate();
}
private int revalidateIndex(int indexAt, int indx) {
if (indx < 0)
indx = leopard.length - 1;
if (indx > (leopard.length - 1))
indx = 0;
index.set(indexAt, indx);
return indx;
}
}
I am trying to create a JDialog using GridBagLayout but I cannot get things looking the way I want. Am I perhaps using the wrong layout model? My code is:
import java.awt.Dialog;
import java.awt.Dialog;
import java.awt.GridBagLayout;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class alertDialog {
JDialog dialog=null;
private GridBagLayout layout=new GridBagLayout();
private NumberFormat tempFormat = NumberFormat.getIntegerInstance();
public alertDialog(String type_,TimelineRecord timeLine_) {
dialog=new JDialog();
dialog.setTitle("Alert");
dialog.setSize(600, 200);
dialog.setLayout(layout);
dialog.setModalityType(Dialog.ModalityType.MODELESS);
dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Monitor mon=timeLine_.monitor;
int row=1;
JLabel msg=new JLabel();
if (type_.equals("Temperature")) {
msg.setText(mon.getName()+" temperature has been reached");
}
else {
msg.setText(type_);
}
JButton dismiss=new JButton("Dismiss");
dismiss.addActionListener(new delayButton(timeLine_,dialog));
JButton delay5=new JButton("Delay 5 Minutes");
delay5.addActionListener(new delayButton(5,timeLine_,dialog));
JButton delay10=new JButton("Delay 10 Minutes");
delay10.addActionListener(new delayButton(10,timeLine_,dialog));
JButton delay15=new JButton("Delay 15 Minutes");
delay15.addActionListener(new delayButton(15,timeLine_,dialog));
dialog.add(msg,makeGbc(0,row++));
dialog.add(dismiss,makeGbc(1,row++));
if (mon!=null) {
JLabel currentTemp=new JLabel("Current Temperature");
JLabel newTarget=new JLabel("New Target");
JFormattedTextField temp=new JFormattedTextField(tempFormat);
temp.setText(Double.toString(mon.current));
JFormattedTextField target=new JFormattedTextField(tempFormat);
target.setText(Double.toString(mon.target));
dialog.add(currentTemp,makeGbc(0,row));
dialog.add(temp,makeGbc(1,row));
dialog.add(newTarget,makeGbc(2,row));
dialog.add(target,makeGbc(3,row++));
}
dialog.add(delay5,makeGbc(0,row));
dialog.add(delay10,makeGbc(1,row));
dialog.add(delay15,makeGbc(2,row));
dialog.setVisible(true);
}
public static void main(String[] args) {
TimelineRecord timeline=new TimelineRecord();
new alertDialog("tod",timeline);
}
}
Here is the TimeLineRecord:
import java.util.Timer;
public class TimelineRecord {
// text of event to take place (Saved to XML)
public String eventText;
// time of day for alarm (Saved to XML)
public String tod;
// target temp for alarm (Saved to XML)
public double targetTemp;
// pit temp to change to (Saved to XML)
public double pitTemp;
// meat type
public String meat;
// weight of meat
public double weight;
// Average cook time for this probe in minutes (Saved to XML)
public long avgCookTime;
// total cook time in minutes
public long totalCookTime;
// associated monitor instance (ID saved to XML)
public Monitor monitor=null;
// associated pit probe instance (ID saved to XML)
public Monitor pit=null;
// timer for alarm instance
public Timer timer=null;
// actual time of event
public String actualTod;
// actual temp at event
public double actualTemp;
// actual pit temp at event
public double actualPitTemp;
// Method to set variables
public void setObject(String obj_,String value_) {
switch(obj_) {
case "eventText": eventText=value_;
break;
case "tod": tod=value_;
break;
case "targetTemp": if (!value_.equals("")) {
targetTemp=Double.parseDouble(value_);
}
break;
case "pitTemp": if (!value_.equals("")) {
pitTemp=Double.parseDouble(value_);
}
break;
case "meat": meat=value_;
break;
case "weight": if (!value_.equals("")) {
weight=Double.parseDouble(value_);
}
break;
}
}
}
The Listener:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
public class delayButton implements ActionListener {
private int delay=0;
private TimelineRecord timeLine=null;
private JDialog dialog=null;
public delayButton(int minutes_,TimelineRecord timeLine_,JDialog dialog_) {
delay=minutes_;
timeLine=timeLine_;
dialog=dialog_;
}
public delayButton(TimelineRecord timeLine_,JDialog dialog_) {
timeLine=timeLine_;
dialog=dialog_;
}
#Override
public void actionPerformed(ActionEvent arg0) {
if (delay==0) {
System.out.println("Got dismiss for "+timeLine.monitor.getName());
}
else {
System.out.println("Got "+Integer.toString(delay)+" minute delay for "+timeLine.monitor.getName());
}
dialog.dispose();
}
}
And the GBC generator:
public static GridBagConstraints makeGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
Insets WEST_INSETS=new Insets(5,0,5,5);
Insets EAST_INSETS=new Insets(5,5,5,0);
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
The first line can be any length so I want it to be centered based on length. The button on the second line should be centered. Oddly, the height of the first button in the last line is different from the other buttons. They should all be the same.
try this
import javax.swing.*;
import java.awt.*;
public class AlertDialog extends JDialog {
public AlertDialog(Frame owner) {
super(owner);
createGUI();
}
public AlertDialog(Dialog owner) {
super(owner);
createGUI();
}
private void createGUI() {
JLabel label = new JLabel("My Label");
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
topPanel.add(label);
JButton button = new JButton("Button");
JPanel centerPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
centerPanel.add(button, c);
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
JPanel bottomPanel = new JPanel(new GridLayout(0, 3));
bottomPanel.add(button1);
bottomPanel.add(button2);
bottomPanel.add(button3);
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
pack();
setLocationRelativeTo(getParent());
}
}
and version with one panel
import javax.swing.*;
import java.awt.*;
public class AlertDialog extends JDialog {
public AlertDialog(Frame owner) {
super(owner);
createGUI();
}
public AlertDialog(Dialog owner) {
super(owner);
createGUI();
}
private void createGUI() {
JLabel label = new JLabel("My Label");
JButton button = new JButton("Button");
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 3;
add(label, c);
c.gridy++;
c.weightx = 1.0;
c.weighty = 1.0;
add(button, c);
c.gridy++;
c.gridwidth = 1;
c.weighty = 0.0;
c.fill = GridBagConstraints.HORIZONTAL;
add(button1, c);
c.gridx++;
add(button2, c);
c.gridx++;
add(button3, c);
pack();
setLocationRelativeTo(getParent());
}
}
in your code this resize first button on last row (x = 0)
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL
(Sorry if this question is not done properly, I'm new. But at least I researched a lot before asking my own question)
Hello. I'm writing a blackjack game in java and it's turning quite massive. My problem is how to handle multiple instances of swing components, I guess you can call it. I can't figure out wether to create the components (such as jpanels and jbuttons) as class level, or in specific methods.
If I create them in their corresponding method, then my action listener can't see them, but if I create them as class level, then they get deleted when I call dispose().
class BlackjackGame extends JFrame implements ActionListener{
public void mainMenu(){
JPanel menuPane = new JPanel(new GridBagLayout()); //Init of main menu
GridBagConstraints c = new GridBagConstraints();
menuPane.setBackground(new Color(125,0,0));
menuPane.setBounds(620,220,175,250);
JLabel menuTitle = new JLabel("Welcome to Blackjack!");//Main menu-content
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
menuPane.add(menuTitle, c);
JButton playButton = new JButton("Play!");
playButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
menuPane.add(playButton, c);
JButton exitButton = new JButton("Exit!");
exitButton.addActionListener(this);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 3;
menuPane.add(exitButton, c);
JButton rulesButton = new JButton("Set rules.");
rulesButton.addActionListener(this);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
menuPane.add(rulesButton, c);
this.add(menuPane,0);
}
//This is where I get problems
public void actionPerformed (ActionEvent event){
if(event.getSource() == playButton){
//I want the menuPane to disappear, and a transition into the game.
menuPane.dispose();
//Call method for the rest of the game.
}else if(event .getSource() etcetera etcetera){
etcetera etcetera
}
}
}
When done this way, the actionlistener cannot find my components, such as playButton or menuPane. But if I had introduced them as class level objects:
class BlackjackGame extends JFrame implements ActionListener{
JPanel menuPane = new JPanel(new GridBagLayout());
JLabel menuTitle = new JLabel("Welcome to Blackjack!");
JButton playButton = new JButton("Play!");
JButton exitButton = new JButton("Exit!");
JButton rulesButton = new JButton("Set rules.");
public void mainMenu(){
//Rest of code
}
public void actionPerformed(ActionEvent event){
menuPane.dispose();
//Rest of code
}
}
...then as I call menuPane.dispose(), how can I get it back when I want to call mainMenu() again? If I want to go back to the main menu, then I would need to create a new instance of menuPane, as well as all the buttons, but as they are class level and already disposed I can't.
Please help me, and thank you!
PS. I can post my full code as it is atm if it would help.
Edit: Dan's answer has been accepted, as it was indeed the correct answer and it worked for my specific program very well. Thank you and merry christmas!
First, unless I've misunderstood your code, menuPane.dispose() shouldn't work as JPanel does not have a function called dispose()
The best way to do what you want to do if you want to use the same menuPane for the menu. Instead of menuPane.dispose(); use remove(menuPane); and then add(yourOtherPanel);
Working Example
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class BlackjackGame extends JFrame implements ActionListener {
private JPanel menuPane;
private JLabel menuTitle;
private JButton playButton;
private JButton exitButton;
private JButton rulesButton;
private JPanel otherPane;
private JLabel otherTitle;
private JButton otherButton;
public BlackjackGame() {
mainMenu();
otherPanel();
setSize(400, 400);
setVisible(true);
}
private void mainMenu() {
menuPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
menuPane.setBackground(new Color(125,0,0));
menuPane.setBounds(620,220,175,250);
menuTitle = new JLabel("Welcome to Blackjack!");
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
menuPane.add(menuTitle, c);
playButton = new JButton("Play!");
playButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
menuPane.add(playButton, c);
exitButton = new JButton("Exit!");
exitButton.addActionListener(this);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 3;
menuPane.add(exitButton, c);
rulesButton = new JButton("Set rules.");
rulesButton.addActionListener(this);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
menuPane.add(rulesButton, c);
add(menuPane);
}
private void otherPanel() {
otherPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
otherPane.setBackground(new Color(125,0,0));
otherPane.setBounds(620,220,175,250);
otherTitle = new JLabel("Welcome to Second Pane!");
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
otherPane.add(otherTitle, c);
otherButton = new JButton("Go Back!");
otherButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
otherPane.add(otherButton, c);
}
public void actionPerformed (ActionEvent event) {
if(event.getSource() == playButton) {
remove(menuPane);
add(otherPane);
validate();
repaint();
} else if(event.getSource() == otherButton) {
remove(otherPane);
add(menuPane);
validate();
repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new BlackjackGame());
}
}
Edit for comments
So the java method remove() only removes the object from the container, which in this case is the JFrame. This method does not effect the object it moves so the object can be reused later. Hence why in the code above I can just use the remove() and add() methods without redeclaring or remaking menuPane and otherPane.
As for why I declare the objects like this
`private JPanel menuPane;`
And then initialize like this
menuPane = new JPanel(new GridBagLayout());
This is because I want the ActionListener to be able to see the objects without initializing them straight away. The line private JPanel menuPane; makes the object a global variable and the line menuPane = new JPanel(new GridBagLayout()); makes it into what I am going to use. Doing it this way instead of JPanel menuPane = new JPanel(new GridBagLayout()); also means I can reuse the same variable in multiple methods. For example
private JPanel panel;
private void createPanelOne() {
panel = new JPanel(new FlowLayout());
...
add(panel);
}
private void createPanelTwo() {
panel = new JPanel(new GridBagLayout());
...
add(panel);
}
After doing this, you will have two JPanels in your JFrame and they will be different, but you only need to use one JPanel
This is the other way of declaring it and it makes a local variable. Local variables aren't visible to other methods outside of the method you are using unless you pass them through.
JPanel panel = new JPanel();
I wouldn't say this is a con in the slightest. I think sometimes it is good to use local variables in a method that shouldn't be visible to other methods.
Finally to pass local variables through to other methods you can use arguments in a method you have made. For example
public void setSomeValue(int val) {
someValue = val;
}
I'm creating a simple gui of options that containing a JScrollPanel.
The problem is when I'm scrolling all the content of the JPanel inside my JScrollPanel doesn't refresh like that :
Bad Refresh Scrolling
Another issues is that not all my text fields are well painted and the combobox fields are behind the first text field.
Here my code :
OptionsPanel.java the source of the problem
package scroll;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import scroll.NavigationButtons.Navigation;
public class OptionsPanel extends JPanel implements ActionListener, TextListener {
private static final long serialVersionUID = 3800714599366218432L;
private NavigationButtons navBtn;
private ChangeOptionCB language;
private ChangeOptionTF option1;
private ChangeOptionTF option2;
private ChangeOptionTF option3;
private ChangeOptionTF option4;
private ChangeOptionTF option5;
private ChangeOptionTF option6;
private ChangeOptionTF option7;
private JScrollPane scrollPane;
public OptionsPanel() {
super();
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints constraint = new GridBagConstraints();
JPanel optionsPanel = new JPanel();
GridBagLayout l = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
optionsPanel.setLayout(l);
String[] langues = {"en", "fr", "es"};
language = new ChangeOptionCB("Languages", langues);
language.addTextListener(this);
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(language, c);
option1 = new ChangeOptionTF("option 1");
option1.addTextListener(this);
option1.setText("option 1");
c.gridx = 0;
c.gridy = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option1, c);
option2 = new ChangeOptionTF("option 2");
option2.addTextListener(this);
option2.setText("option 2");
c.gridx = 0;
c.gridy = 2;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option2, c);
option3 = new ChangeOptionTF("option 3");
option3.addTextListener(this);
option3.setText("option 3");
c.gridx = 0;
c.gridy = 3;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option3, c);
option4 = new ChangeOptionTF("option 4");
option4.addTextListener(this);
option4.setText("option 4");
c.gridx = 0;
c.gridy = 4;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option4, c);
option5 = new ChangeOptionTF("option 5");
option5.addTextListener(this);
option5.setText("option 5");
c.gridx = 0;
c.gridy = 5;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option5, c);
option6 = new ChangeOptionTF("option 6");
option6.addTextListener(this);
option6.setText("option 6");
c.gridx = 0;
c.gridy = 6;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option6, c);
option7 = new ChangeOptionTF("option 7");
option7.addTextListener(this);
option7.setText("option 7");
c.gridx = 0;
c.gridy = 7;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.weightx = 1;
c.weighty = 0.1;
optionsPanel.add(option7, c);
scrollPane = new JScrollPane(optionsPanel);
constraint.gridx = 0;
constraint.gridy = 0;
constraint.fill = GridBagConstraints.BOTH;
constraint.weightx = 1;
constraint.weighty = 1;
add(scrollPane, constraint);
navBtn = new NavigationButtons(NavigationButtons.EXIT);
navBtn.addActionListener(this);
constraint.gridx = 0;
constraint.gridy = 1;
constraint.fill = GridBagConstraints.HORIZONTAL;
constraint.weightx = 1;
constraint.weighty = 0.25;
add(navBtn, constraint);
}
#Override
public void actionPerformed(ActionEvent ae) {
if (navBtn == ae.getSource()) {
int id = ae.getID();
if (Navigation.EXIT.getId() == id) {
System.out.println("Get out !!");
}
}
}
#Override
public void textValueChanged(TextEvent te) {
if (language == te.getSource()) {
System.out.println("The option as changed : "+language.getOption());
}
if (option1 == te.getSource()) {
System.out.println("The option as changed : "+option1.getNewText());
}
if (option2 == te.getSource()) {
System.out.println("The option as changed : "+option2.getNewText());
}
if (option3 == te.getSource()) {
System.out.println("The option as changed : "+option3.getNewText());
}
if (option4 == te.getSource()) {
System.out.println("The option as changed : "+option4.getNewText());
}
if (option5 == te.getSource()) {
System.out.println("The option as changed : "+option5.getNewText());
}
if (option6 == te.getSource()) {
System.out.println("The option as changed : "+option6.getNewText());
}
if (option7 == te.getSource()) {
System.out.println("The option as changed : "+option7.getNewText());
}
scrollPane.revalidate();
scrollPane.repaint();
}
}
The Main Class
package scroll;
import java.awt.Dimension;
import javax.swing.JFrame;
public class ScrollTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setContentPane(new OptionsPanel());
frame.setTitle("Scrool Test");
frame.pack();
Dimension dimension = new Dimension(691, 263);
frame.setSize(dimension);
frame.setPreferredSize(dimension);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}
The different stuff that you need :
package scroll;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.event.EventListenerList;
public class ChangeOptionCB extends JPanel implements ActionListener {
private static final long serialVersionUID = 3355314012553851743L;
private JComboBox cb;
private JButton saveBtn;
private EventListenerList listeners;
public ChangeOptionCB(String label, String[] list) {
listeners = new EventListenerList();
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(layout);
JLabel jLabel = new JLabel(label);
jLabel.setHorizontalAlignment(SwingConstants.LEFT);
c.fill = GridBagConstraints.LINE_START;
c.gridx = 0;
c.gridy = 0;
c.weightx = 0.1;
add(jLabel, c);
cb = new JComboBox(list);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 0;
c.weightx = 0.8;
add(cb, c);
saveBtn = new JButton("Save");
saveBtn.addActionListener(this);
c.gridx = 2;
c.gridy = 0;
c.weightx = 0;
c.anchor = GridBagConstraints.LINE_END;
add(saveBtn, c);
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == saveBtn) {
fireTextAsChange();
}
}
public String getOption() {
return (String) cb.getSelectedItem();
}
public void addTextListener(TextListener listener) {
listeners.add(TextListener.class, listener);
}
public void removeActionListener(TextListener listener) {
listeners.remove(TextListener.class, listener);
}
private void fireTextAsChange(){
TextListener[] listenerList = (TextListener[])listeners.getListeners(TextListener.class);
for(TextListener listener : listenerList){
listener.textValueChanged(new TextEvent(this, 0));
}
}
}
package scroll;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.EventListenerList;
public class ChangeOptionTF extends JPanel implements ActionListener {
private static final long serialVersionUID = 3355314012553851743L;
private TextField tf;
private JButton saveBtn;
private EventListenerList listeners;
public ChangeOptionTF(String label) {
listeners = new EventListenerList();
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(layout);
JLabel jLabel = new JLabel(label);
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
add(jLabel, c);
tf = new TextField();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
c.weightx = 0.5;
add(tf, c);
saveBtn = new JButton("Save");
saveBtn.addActionListener(this);
c.gridx = 2;
c.gridy = 1;
c.weightx = 0;
c.anchor = GridBagConstraints.LINE_END;
add(saveBtn, c);
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == saveBtn) {
fireTextAsChange();
}
}
public String getNewText() {
return tf.getText();
}
public void addTextListener(TextListener listener) {
listeners.add(TextListener.class, listener);
}
public void removeActionListener(TextListener listener) {
listeners.remove(TextListener.class, listener);
}
private void fireTextAsChange(){
TextListener[] listenerList = (TextListener[])listeners.getListeners(TextListener.class);
for(TextListener listener : listenerList){
listener.textValueChanged(new TextEvent(this, 0));
}
}
public void setText(String text) {
tf.setText(text);
}
}
package scroll;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.event.EventListenerList;
public class NavigationButtons extends JPanel implements ActionListener {
private static final long serialVersionUID = -4844499317626526067L;
public enum Navigation {
NEXT(1), CANCEL(0), EXIT(-1);
private int id;
private Navigation(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
public static int NEXT_CANCEL = 0;
public static int CANCEL = 1;
public static int EXIT = 2;
private JButton cancel;
private JButton next;
private JButton exit;
private EventListenerList listeners;
public NavigationButtons(int type) {
listeners = new EventListenerList();
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(layout);
if ((NEXT_CANCEL == type) || (CANCEL == type)) {
cancel = new JButton("Cancel");
cancel.addActionListener(this);
c.gridwidth = 1;
c.anchor = GridBagConstraints.LINE_START;
c.weightx = 1;
add(cancel, c);
}
if (NEXT_CANCEL == type) {
next = new JButton("Next");
next.addActionListener(this);
c.gridwidth = 1;
c.anchor = GridBagConstraints.LINE_END;
c.weightx = 0;
add(next, c);
}
if (EXIT == type) {
exit = new JButton("Exit");
exit.addActionListener(this);
c.gridwidth = 1;
c.anchor = GridBagConstraints.LINE_END;
c.weightx = 1;
add(exit, c);
}
}
public void setNextEnable(boolean b) {
next.setEnabled(b);
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == next) {
fireActionPerformed(Navigation.NEXT);
}
if (ae.getSource() == cancel) {
fireActionPerformed(Navigation.CANCEL);
}
if (ae.getSource() == exit) {
fireActionPerformed(Navigation.EXIT);
}
}
public void addActionListener(ActionListener listener) {
listeners.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listeners.remove(ActionListener.class, listener);
}
public void fireActionPerformed(Navigation nav){
ActionListener[] listenerList = (ActionListener[])listeners.getListeners(ActionListener.class);
for(ActionListener listener : listenerList){
listener.actionPerformed(new ActionEvent(this, nav.getId(), null));
}
}
}
What is wrong in my code that make this ugly refresh ? I don't understand.
Maybe I need to implement a kind of listener that repaint my frame each time I scroll ?
The more strange things is, if I replace
add(scrollPane, constraint);
by
add(optionsPane, constraint);
the content get out well (at least in this example).
Thank's you
Julien
The basic problem is, you're using java.awt.TextField which is a heavy weight component inside a lighweight container. This is just asking for issues, they tend not to play well together.
Instead, use a javax.swing.JTextField
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.EventListenerList;
public class ChangeOptionTF extends JPanel implements ActionListener {
private static final long serialVersionUID = 3355314012553851743L;
private JTextField tf;
private JButton saveBtn;
private EventListenerList listeners;
public ChangeOptionTF(String label) {
listeners = new EventListenerList();
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(layout);
JLabel jLabel = new JLabel(label);
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
add(jLabel, c);
tf = new JTextField();
I'm having an issue adding JScrollPane in JTextArea using GridBagLayout. Basically the program runs fine when the scrollbar isn't needed but the layout gets messed up and the content gets cut off when it is. The relevent code is as follows
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class testGUI extends JFrame
{
public static String name;
static JTextField textfield = new JTextField(30);
static JTextArea textarea = new JTextArea(30,30);
public static void main( String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Checkem");
frame.setLocation(500,400);
frame.setSize(800,800);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JScrollPane scrolltxt = new JScrollPane(textarea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrolltxt.setWheelScrollingEnabled(true);
scrolltxt.getVerticalScrollBar().isVisible();
panel.add(scrolltxt, c);
JLabel label = new JLabel("Enter the Name of the file:");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(2,2,2,2);
panel.add(label,c);
c.gridx = 0;
c.gridy = 1;
panel.add(textarea,c);
JButton button = new JButton("Search");
c.gridx = 1;
c.gridy = 1;
panel.add(button,c);
c.gridx = 1;
c.gridy = 0;
panel.add(textfield,c);
frame.getContentPane().add(panel, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
Checkem record = new Checkem();
name = textfield.getText();
String [] print = record.run(name);
for (int i=0;i<print.length;i++)
{
if(print[i] == null || print[i].isEmpty())
{
continue;
}
else
{
textarea.append(print[i] + "\n");
}
}
}
});
}
}
I'm really new to swing and I'm really at a loss where to go from here. Thanks for all your help.
First please learn Java Naming Conventions, that makes it a bit easier for the other person to understand the Java code.
Now to the actual thingy :-)
Why not simply use JTextArea.setLineWrap(true) and
JTextArea.setWrapStyleWord(true) instead of defining JScrollBar policy,
this will even look nice on the view :-)
Moreover, instead of specifying setSize()/setLocation() methods,
simply use frameReference.pack() and
frame.setLocationByPlatform(true), a very wonderful answer
regarding the benefit of the latter is mentioned in this answer, how
to best position Swing GUIs
Do not make so many static fields in a class, this smells like a bad
programming design, and makes your class less extensible.
You are extending JFrame to your TestGUI class and then inside
it's main() method you creating an instance of the same. Actually
again, try to give more weightage to composition over inheritance, since
over here, you not actually trying to modify the already defined
features of JFrame, instead you just using them as is, so there is
no need to extend JFrame in this case atleast :-)
Read about Concurrency in Swing
Here is your modified code :
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class TestGUI {
private String name;
private JTextField textfield = new JTextField(30);
private JTextArea textarea = new JTextArea(30,30);
private void displayGUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Checkem");
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
textarea.setLineWrap(true);
textarea.setWrapStyleWord(true);
JScrollPane scrolltxt = new JScrollPane();
scrolltxt.setViewportView(textarea);
scrolltxt.setWheelScrollingEnabled(true);
JLabel label = new JLabel("Enter the Name of the file:");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(2,2,2,2);
panel.add(label,c);
c.gridx = 0;
c.gridy = 1;
panel.add(scrolltxt,c);
JButton button = new JButton("Search");
c.gridx = 1;
c.gridy = 1;
panel.add(button,c);
c.gridx = 1;
c.gridy = 0;
panel.add(textfield,c);
frame.getContentPane().add(panel, BorderLayout.NORTH);
//frame.setSize(800,800);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
/*Checkem record = new Checkem();
name = textfield.getText();
String [] print = record.run(name);
for (int i=0;i<print.length;i++)
{
if(print[i] == null || print[i].isEmpty())
{
continue;
}
else
{
textarea.append(print[i] + "\n");
}
}*/
}
});
}
public static void main( String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new TestGUI().displayGUI();
}
};
EventQueue.invokeLater(r);
}
}
You add the JScrollPane, but then you add the JLabel into the same grid position. Then you add the raw JTextArea without the JScrollPane later.
Try this which only adds the JScrollPane that contains your JTextArea. I also moved your GUI creation into a constructor that is called with a SwingUtilities.invokeLater call to ensure it is on the EDT. See Concurrency in Swing for more details on the EDT. This also allows you to not have all your class member variables static, which is not very good practice.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestGUI extends JFrame {
String name;
JTextField textfield = new JTextField(30);
JTextArea textarea = new JTextArea(30, 30);
public TestGUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JScrollPane scrolltxt = new JScrollPane(textarea);
JLabel label = new JLabel("Enter the Name of the file:");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(2, 2, 2, 2);
panel.add(label, c);
c.gridx = 0;
c.gridy = 1;
panel.add(scrolltxt, c);
JButton button = new JButton("Search");
c.gridx = 1;
c.gridy = 1;
panel.add(button, c);
c.gridx = 1;
c.gridy = 0;
panel.add(textfield, c);
frame.getContentPane().add(panel, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Checkem record = new Checkem();
name = textfield.getText();
String [] print = record.run(name);
for (int i=0;i<print.length;i++) {
if(print[i] == null || print[i].isEmpty()) {
continue;
} else {
textarea.append(print[i] + "\n");
}
}
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestGUI();
}
});
}
}