How to open another program with for statements java? - java

I'm very new to java I have been doing basic stuff and for my final project we wanted to create a gui rpg. Our problem right now is we can't figure out how to open another program by clicking the gui button. My friends told me you guys use eclipse so I don't have to show imports. Keep in mind I'm in highschool so don't judge too harsh :D Here is our code:
public class Narnia {
private static final String BACKHGROUND_IMAGE_URL = "http://randomwallpapers.net/fantasy-castle-1920x1080-wallpaper328374.jpg";
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(Narnia.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageIcon backgroundImage = new ImageIcon(new URL(BACKHGROUND_IMAGE_URL));
JLabel mainPanel = new JLabel(backgroundImage) {
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
Dimension lmPrefSize = getLayout().preferredLayoutSize(this);
size.width = Math.max(size.width, lmPrefSize.width);
size.height = Math.max(size.height, lmPrefSize.height);
return size;
}
};
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Play" + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Credits " + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Exit " + ("")), gbc);
}
// Let's put a filler bottom component that will push the rest to the top
gbc.weighty = 1.0;
mainPanel.add(Box.createGlue(), gbc);
frame.add(mainPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new Narnia().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Here is the class we want to open:
public class chooseaclass {
private static final String BACKHGROUND_IMAGE_URL = "http://randomwallpapers.net/fantasy-castle-1920x1080-wallpaper328374.jpg";
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(chooseaclass.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageIcon backgroundImage = new ImageIcon(new URL(BACKHGROUND_IMAGE_URL));
JLabel mainPanel = new JLabel(backgroundImage) {
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
Dimension lmPrefSize = getLayout().preferredLayoutSize(this);
size.width = Math.max(size.width, lmPrefSize.width);
size.height = Math.max(size.height, lmPrefSize.height);
return size;
}
};
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(40, 40, 40, 40);
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Archer" + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Mage " + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Knight " + ("")), gbc);
}
// Let's put a filler bottom component that will push the rest to the top
gbc.weighty = 1.0;
mainPanel.add(Box.createGlue(), gbc);
frame.add(mainPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new chooseaclass().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}

You need to add a listener to whatever button you want. In this case, we'll use an ActionListener.
Let's just use this existing line that you already have: mainPanel.add(new JButton("Play" + ("")), gbc);
First of all, to make it simpler, let's put that JButton in a variable:
JButton playButton = new JButton("Play" + (""));
To add a listener, we need to use the method addActionListener().
Now add an ActionListener as an anonymous class so that we can implement a method that the system can call behind the scenes:
JButton playButton = new JButton("Play" + (""));
playButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
new chooseaclass.initUI() //insantiate a new chooseaclass instance
}
});
mainPanel.add(playButton, gbc);
Within the actionPerformed() method, I instantiated a chooseaclass. You can do whatever you want from there.
I wrote this code off the cuff without an editor so it may contain syntax errors.

Related

How to know which reference is static in Java

I am currently working on GUI of simple food ordering system. I created a button that whenever user clicks it it will go to another frame, however I am facing problem when I want to close the first frame (setVisible(false)).
This is my first frame
public class MainFrame extends JFrame {
private Manager manager = new Manager();
private JPanel titlepane;
private JLabel title;
MainFrame(String name){
setTitle(name);
}
public void content() {
Font titlefont = new Font("Times New Roman", Font.PLAIN, 22);
setLayout(new BorderLayout());
titlepane = new JPanel();
title = new JLabel("Welcome to POS!");
title.setFont(titlefont);
titlepane.add(title);
manager.LoginGUI();
add(titlepane,BorderLayout.NORTH);
add(manager,BorderLayout.CENTER);
}
public void runGUI() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
content();
setSize(700,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
}
});
}
This is another class where the button is
public class Manager extends JPanel implements ActionListener {
private ArrayList<AccountInfo> manager = new ArrayList<AccountInfo>();
private GridBagConstraints gbc = new GridBagConstraints();
private JLabel id;
private JLabel pw;
private JTextField idfill;
private JTextField pwfill;
private JButton login;
private int isManager = 0;
private String idinput, pwinput;
private int temp = -1;
Manager() {
this.manager.add(new AccountInfo("admin", "1234"));
}
public void addManager(AccountInfo newManager) {
this.manager.add(newManager);
}
public void LoginGUI() {
Font standard = new Font("Times New Roman", Font.PLAIN, 18);
setLayout(new GridBagLayout());
id = new JLabel("ID");
id.setFont(standard);
// Alignment
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 10;
gbc.ipady = 10;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(id, gbc);
idfill = new JTextField(10);
idfill.setFont(standard);
// Alignment
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(idfill, gbc);
pw = new JLabel("Password");
pw.setFont(standard);
// Alignment
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(pw, gbc);
pwfill = new JTextField(10);
pwfill.setFont(standard);
// Alignment
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(pwfill, gbc);
login = new JButton("Login");
login.setFont(standard);
login.addActionListener(this);
// Alignment
gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(login, gbc);
}
public void actionPerformed(ActionEvent e) {
verify();
if(isManager == 1) {
MenuFrame menu = new MenuFrame("Menu");
menu.runGUI();
MainFrame.setVisible(false); // This is the problem
}
}
private void verify() {
idinput = idfill.getText().trim();
pwinput = pwfill.getText();
for (int i = 0; i < manager.size(); i++) {
if (idinput.equals(manager.get(i).id)) {
temp = i;
}
}
if(temp == -1) {
JOptionPane.showMessageDialog(null, "Id or password incorrect, try again");
} else if(pwinput.equals(manager.get(temp).password)) {
isManager = 1;
} else
JOptionPane.showMessageDialog(null, "Id or password incorrect, try again");
}
}
(The codes are a bit lengthy as I am not confident that the other part was correct. All I know this has nothing to do with MenuFrame)
I get this error:
Cannot make a static reference to the non-static method setVisible(boolean) from the type Window
It might be my fault where it is not obvious enough for me to know which part of Manager or MainFrame is static. I also came across other posts regarding the same issue but none relates with mine. (Other post was having obvious static method)
Also tried the create an MainFrame object in Manager but it made it worse, please help, thank you!
You indeed need to keep the MainFrame object somewhere accessible, keep a reference to it. For this MVC, Model-View-Controller, is a nice paradigm.
Use MVC
I personally have my main method for swing in a Controller class (so the controller is the application class). It creates the main frame (View) and the controller is passed.
public void actionPerformed(ActionEvent e) {
verify();
if(isManager == 1) {
MenuFrame menu = new MenuFrame("Menu");
menu.runGUI();
controller.setMainFrameVisible(false);
}
}
Controller:
private MainFrame mainFrame;
public setMainFrameVisible(boolean visible) {
MainFrame.setVisible(visible);
}
Pass the MainFrame instance.
However you may also pass the MainFrame:
private final MainFrame mainFrame;
Manager(MainFrame mainFrame) {
this.mainFrame = mainFrame;
}
public void actionPerformed(ActionEvent e) {
verify();
if(isManager == 1) {
MenuFrame menu = new MenuFrame("Menu");
menu.runGUI();
mainFrame.setVisible(false);
}
}
If the panel is inside the MainFrame
((JFrame) getTopLevelAncestor()).setVisible(false);
Tip:
Should the application exit (EXIT_ON_CLOSE), change the default close operation.
MainFrame(String name){
setTitle(name);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}

Spaces between elements in GridLayout and GridBagLayout

I am trying to create a grid of text fields which I envision would look like this:
I am trying to use Swing in order to do this but am having trouble creating the grid. I have tried both GridBagLayout and GridLayout in order to accomplish this but have had the same issue with both - I am unable to remove spaces between the text fields.
The above image is using grid bag layout. I have tried to change the insets as well as the weights of each text field but have not been able to get rid of the spaces between the fields.
The grid layout is slightly better:
But it has the same problem. I tried adding each text field to a JPanel and then created an empty border for each panel but this also did not work.
I have attached the code for both implementations. I am not committed to using a JTextField so if there is some other element that a user can type into I would be willing to try that out as well. Any help getting rid of the spaces between each text field would be greatly appreciated!
GridBagLayoutDemo
class GridBagLayoutDemo {
public static void addComponentsToPane(Container pane) {
GridBagLayout gbl = new GridBagLayout();
pane.setLayout(gbl);
GridBagConstraints c = new GridBagConstraints();
int rows = 2;
int cols = 2;
for(int i = 0; i < (rows + 1) * 3; i++){
JTextField textField = new JTextField(1);
textField.setFont( new Font("Serif", Font.PLAIN, 30) );
JPanel tempPanel = new JPanel();
tempPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
tempPanel.add(textField);
c.gridx = i % (rows + 1);
c.gridy = i / (cols + 1);
c.gridheight = 1;
c.gridwidth = 1;
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
pane.add(tempPanel, c);
}
gbl.setConstraints(pane, c);
c.insets = new Insets(0,0,0,0);
}
public void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
GridBagLayoutDemo demo = new GridBagLayoutDemo();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
demo.createAndShowGUI();
}
});
}
}
GridLayoutDemo
class GridLayoutDemo {
public void createAndShowGUI() {
JFrame frame = new JFrame("GridLayout");
//frame.setOpacity(0L);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel parentPanel = new JPanel();
GridLayout layout = new GridLayout(3, 3, 0, 0);
layout.setHgap(0);
layout.setVgap(0);
parentPanel.setLayout(layout);
for(int i = 0 ; i < 9; i++){
JTextField textField = new JTextField();
textField.setHorizontalAlignment(JTextField.CENTER);
// JPanel tempPanel = new JPanel();
//textField.setBounds(0, 0, 10 , 10);
//textField.setFont( new Font("Serif", Font.PLAIN, 18));
//tempPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
//tempPanel.add(textField);
// tempPanel.add(textField);
parentPanel.add(textField);
}
frame.add(parentPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
GridLayoutDemo demo = new GridLayoutDemo();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
demo.createAndShowGUI();
}
});
}
}
I think you will find that this is a issue with the MacOS look and feel, as it adds a empty border around the text fields to allow for the focus highlight
You can see it highlighted below
The simplest way to remove it, is to remove or replace the border, for example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
int rows = 3;
int cols = 3;
for (int index = 0; index < (rows * cols); index++) {
int row = index % rows;
int col = index / cols;
gbc.gridy = row;
gbc.gridx = col;
JTextField textField = new JTextField(4);
textField.setText(col + "x" + row);
textField.setBorder(new LineBorder(Color.DARK_GRAY));
add(textField, gbc);
}
}
}
}

Java not able to close the JFrame

I am not able to close my frame after I click the button. The tricky part is that I do not need to quit the whole application, just close the GUI (not with system exit).
Would you be able to assist me?
Thank you in advance!!!
Main.java
public class Main {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver", "C:/geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://my.emerchantpay.com/");
eMerchantPay emp = PageFactory.initElements(driver, eMerchantPay.class);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new MainFrame("Please enter your credentials");
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
MainFrame.java
public class MainFrame extends JFrame {
private DetailsPanel detailsPanel;
public MainFrame(String title) {
super(title);
// Set layout manager
setLayout(new BorderLayout());
// Create Swing components
final JTextArea textArea = new JTextArea();
detailsPanel = new DetailsPanel();
detailsPanel.addDetailsListener(new DetailListener() {
public void detailEventOccured(DetailEvent event) {
String text = event.getText();
textArea.append(text);
}
});
// Add Swing components to content pane
Container c = getContentPane();
//c.add(textArea, BorderLayout.CENTER);
c.add(detailsPanel, BorderLayout.CENTER);
}
DetailsPanel.java
public class DetailsPanel extends JPanel{
private static final long serialVersionUID = 1234567891;
private EventListenerList listenerList = new EventListenerList();
public DetailsPanel() {
Dimension size = getPreferredSize();
size.width = 250;
setPreferredSize(size);
setBorder(BorderFactory.createTitledBorder("Personal Details"));
JLabel nameLabel = new JLabel("Name: ");
JLabel passwordLabel = new JLabel("Password: ");
final JTextField nameField = new JTextField(10);
final JPasswordField passwordField = new JPasswordField(10);
JButton addBtn = new JButton("Submit");
addBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
String name = nameField.getText();
String password = passwordField.getText();
String text = name + ": " + password + "\n";
System.out.println (text);
}
});
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
/// First column ///
gc.anchor = GridBagConstraints.LINE_END;
gc.weightx = 0.5;
gc.weighty = 0.5;
gc.gridx = 0;
gc.gridy = 0;
add(nameLabel, gc);
gc.gridx = 0;
gc.gridy = 1;
add(passwordLabel, gc);
/// Second column ///
gc.anchor = GridBagConstraints.LINE_START;
gc.gridx = 1;
gc.gridy = 0;
add(nameField, gc);
gc.gridx = 1;
gc.gridy = 1;
add(passwordField, gc);
/// Final row ///
gc.weighty = 10;
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.gridx = 1;
gc.gridy = 2;
add(addBtn, gc);
}
public void fireDetailEvent(DetailEvent event) {
Object[] listeners = listenerList.getListenerList();
for (int i=0; i < listeners.length; i += 2) {
if (listeners[i] == DetailListener.class) {
((DetailListener)listeners[i+1]).detailEventOccured(event);
}
}
}
public void addDetailsListener(DetailListener listener) {
listenerList.add(DetailListener.class, listener);
}
public void removeDetailListener(DetailListener listener) {
listenerList.remove(DetailListener.class, listener);
}
I need to close the frame once I click the login button in this piece of code:
addBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
String name = nameField.getText();
String password = passwordField.getText();
String text = name + ": " + password + "\n";
System.out.println (text);
}
});
In actionPerformed, add these lines to obtain and close the parent frame :
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor(addBtn);
frame.dispose();// or frame.setVisible(false), depending on your needs
Note that you will have to declare your button final in order to use it in the anonymous listener :
final JButton addBtn = new JButton("Submit");

Java swing Button is invisible after revalidate() until clicked

I have a panel with box layout full of buttons {A, B, empty...}. When i try to remove A, I am left with {empty, B, empty}. So i try to add panel.revalidate() but now i have {invisible, empty, empty} and if I mouse over the spot were the button should be and click it appears {B, empty, empty}.
adding panel.repaint() did not help.
Component[] components = Gui.panel.getComponents();
for(int b = 0; b < components.length; b++) {
if(((Button) components[b]).getLabel().contentEquals(parts[2])) {
Gui.panel.remove((Button) components[b]);
Gui.panel.revalidate();
Gui.panel.repaint();
break;
}
}
I also tried to recreate the list skipping the component i wanted omitted but it returns the exact same results.
Component[] components = Gui.panel.getComponents();
Gui.panel.removeAll();
for(int b = 0; b < components.length; b++) {
if(!((Button) components[b]).getLabel().contentEquals(parts[2])) {
Gui.panel.add(components[b]);
}
}
Gui.panel.revalidate();
Gui.panel.repaint();
I know that swing is not thread safe, but i am not sure if that applies here.
The problem is occurring in a runnable class that listens for a message from the server. Although i do a lot of GUI manipulation from the same thread and this is my first problem.
EDIT:
here is a program that highlights my problem:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CreativeName {
public static Thread listen;
static Object VirtualServer = new Object();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Gui.createAndShowGUI();
}
});
listen = new Thread(new FromServer());
listen.start();
}
}
class FromServer implements Runnable {
public void run() {
//Wait for a message from the "server".
synchronized(CreativeName.VirtualServer) {
try {
CreativeName.VirtualServer.wait();
} catch (InterruptedException e) {e.printStackTrace();}
}
//Message received,remove button.
Component[] components = Gui.panel.getComponents();
for(int b = 0; b < components.length; b++) {
if(((Button) components[b]).getLabel().contentEquals("A")) {
Gui.panel.remove((Button) components[b]);
Gui.panel.revalidate();
Gui.panel.repaint();
break;
}
}
}
}
class Gui extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
protected static JPanel panel;
protected static Button remove, A, B;
public Gui() {
super(new GridBagLayout());
remove = new Button("Remove");
remove.setBackground(new Color(250, 200, 200));
remove.addActionListener(this);
A = new Button("A");
A.setBackground(new Color(200, 200, 250));
B = new Button("B");
B.setBackground(new Color(250, 250, 0));
panel = new JPanel(new GridLayout(0,3));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
add(remove, c);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 5;
c.gridheight = 5;
add(panel, c);
panel.add(A);
panel.add(B);
}
public void actionPerformed(ActionEvent event) {
if(event.getSource() == remove) {
//Send a message from the "server".
synchronized(CreativeName.VirtualServer) {
CreativeName.VirtualServer.notify();
}
}
}
static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Button Dilemma");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(300, 400));
//Add contents to the window.
frame.add(new Gui());
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
I set up a monitor to simulate the server and it seems the problem is the thread safety. Perhaps i can reverse the monitor so a message from the server will notify the Gui thread? I don't see were to get a handle on it yet tho.
EDIT: After making sure that the call occurs on the EDT I am getting the same results.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CreativeName {
public static Thread listen;
static Object VirtualServer = new Object();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Gui.createAndShowGUI();
}
});
listen = new Thread(new FromServer());
listen.start();
}
}
class FromServer implements Runnable {
public void run() {
//Wait for a message from the "server".
synchronized(CreativeName.VirtualServer) {
try {
CreativeName.VirtualServer.wait();
} catch (InterruptedException e) {e.printStackTrace();}
}
//Message received,remove button.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (SwingUtilities.isEventDispatchThread()) {
System.err.println("Is running on EDT");
} else {
System.err.println("Is not running on EDT");
}
Component[] components = Gui.panel.getComponents();
for(int b = 0; b < components.length; b++) {
if(((Button) components[b]).getLabel().contentEquals("A")) {
Gui.panel.remove((Button) components[b]);
Gui.panel.revalidate();
Gui.panel.repaint();
break;
}
}
}
});
}
}
class Gui extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
protected static JPanel panel;
protected static Button remove, A, B;
public Gui() {
super(new GridBagLayout());
remove = new Button("Remove");
remove.setBackground(new Color(250, 200, 200));
remove.addActionListener(this);
A = new Button("A");
A.setBackground(new Color(200, 200, 250));
B = new Button("B");
B.setBackground(new Color(250, 250, 0));
panel = new JPanel(new GridLayout(0,3));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
add(remove, c);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 5;
c.gridheight = 5;
add(panel, c);
panel.add(A);
panel.add(B);
}
public void actionPerformed(ActionEvent event) {
if(event.getSource() == remove) {
//Send a message from the "server".
synchronized(CreativeName.VirtualServer) {
CreativeName.VirtualServer.notify();
}
}
}
static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Button Dilemma");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(300, 400));
//Add contents to the window.
frame.add(new Gui());
//Display the window.
frame.pack();
frame.setVisible(true);
}
}

Fixed size of buttons

There is a JPanel with buttons and textField. TextField filters unnecessary buttons by name. But after delete the size of rest buttons is changing.
The height of buttons must not change after filtering in the textField. How to achieve this?
public class TestViewer {
public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {
public void run() {
JDialog dialog = new TestDialog();
dialog.setLocationRelativeTo(null);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setTitle("Type text and press Enter");
dialog.setSize(300, 700);
dialog.setVisible(true);
dialog.setLocationRelativeTo(null);
dialog.setModal(true);
}
});
}
}
class TestDialog extends JDialog {
public TestDialog() {
getContentPane().add(new JPan
el(), BorderLayout.CENTER);
getContentPane().add(createBtnPanel(), BorderLayout.CENTER);
}
private JPanel createBtnPanel() {
int n = 100;
Final String ArrButtonNames[] = new String[n];
for (int h = 0; h < ArrButtonNames.length; h++) {
if ((h%2)==0){
ArrButtonNames[h]="Filter"+h;
}
else{
ArrButtonNames[h]="Button"+h;
}
}
final JButton ArrButton[] = new JButton[n];
final JPanel btnPanel = new JPanel(new GridLayout(0, ArrButtonNames.length, 1,1));
btnPanel.setLayout(new GridLayout(0, 1));
final JTextField textField = new JTextField();
textField.setColumns(23);
btnPanel.add(textField);
for (int i = 0; i < ArrButtonNames.length; i++) {
String btnString = ArrButtonNames[i];
JButton button = new JButton(btnString);
Dimension d = button.getPreferredSize();
d.setSize(d.getWidth(), d.getHeight()*1);
button.setPreferredSize(d);
button.setSize(d);
button.setMinimumSize(d);
button.setMaximumSize(d);
btnPanel.add(button);
ArrButton[i] = button;
}
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int k = 0; k < ArrButtonNames.length; k++) {
if(ArrButtonNames[k].indexOf(textField.getText())==-1) {
btnPanel.remove(ArrButton[k]);
btnPanel.revalidate();
btnPanel.repaint();
}
}
}
});
JPanel MainPanel = new JPanel();
MainPanel.setLayout(new BorderLayout());
MainPanel.add(btnPanel, BorderLayout.NORTH);
final JScrollPane scrollPane = new JScrollPane(btnPanel);
MainPanel.add(scrollPane, BorderLayout.CENTER);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
return MainPanel;
}
}
You have that effect, because you use GridLayout, which resize components to fill whole cell.
For your purposes I recommend you to use GridBagLayout, that can do what you want.
Try to use next code for filling your btnPanel instead of yours:
final JButton ArrButton[] = new JButton[n];
final JPanel btnPanel = new JPanel();
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx=0;
c.gridy=0;
btnPanel.setLayout(new GridBagLayout());
final JTextField textField = new JTextField();
btnPanel.add(textField,c);
for (int i = 0; i < ArrButtonNames.length; i++) {
String btnString = ArrButtonNames[i];
JButton button = new JButton(btnString);
c.gridy ++;
btnPanel.add(button,c);
ArrButton[i] = button;
}
c.fill = GridBagConstraints.BOTH;
c.weighty = 1;
c.gridy ++;
btnPanel.add(new JLabel(""),c);
And it looks like:
ALso use pack() method instead of setSize(...), and don't use setPreferedSize(...) and others size methods read about that here.

Categories

Resources