Java not able to close the JFrame - java

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");

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);
}

Accessing a string in another class in Java - GUI

Another question for Java... I know it's basic, but I am not pro.
So I have 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);
}
});
emp.uid(username);
emp.pwd(password);
emp.LoginButton.click();
And the string is located in 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);
final 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";
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor(addBtn);
frame.dispose();
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);
}
So the strings are located here
String name = nameField.getText();
String password = passwordField.getText();
How do I access these from Main.java? I have to assign the name value to emp.uid(username);
Your fields are package protected, thus they are visible in the same package.
However, you need an instance of your DetailsPanel to access them.
So, where your Main class uses the DetailsPanel, you could use something like this:
DetailsPanel details = new DeatilsPanel();
...
String name = details.nameField.getText();
char[] password = details.passwordField.getPassword();
(For security reasons JPasswordField does have the getText() method to return the password in a String deprecated.)
You can create two data members in your DetailsPanel.java file and can can name them as name and password.
In your Main.java, you can create an object of DetailsPanel and using the object you can access the values of name and password
Main.java
DetailsPanel obj=new DetailsPanel();
emp.uid(obj.name);
emp.pwd(obj.password);
DetailsPanel.java
class DetailsPanel{
String name;
String password;
}
Hope it helps you to get the basics.

Java JPanel keeps growing with JTextArea

I was testing something with JPanel. When I added random text to the JTextArea inside it, it kept increasing the size of the JPanel until it reached the edge.
How do I keep the text inside the JPanel without stretching it?
public class Game
{
TitleScreenHandler tsHandler = new TitleScreenHandler();
ChoiceHandler choiceHandler = new ChoiceHandler();
ComponentHandler compHandler = new ComponentHandler();
GridBagConstraints gbc = new GridBagConstraints();
Border whiteline = BorderFactory.createLineBorder(Color.WHITE);
JFrame window;
Container con;
JPanel titlePanel , startPanel, mainTextPanel, choiceButtonPanel, playerPanel;
JLabel titleLabel, hpLabel, hpLabelNumber, weaponLabel, weaponLabelName;
public static JButton startButton, choice1,choice2,choice3,choice4,choice5,choice6,choice7,choice8;
public static JTextArea mainTextArea;
Font titleFont = new Font("Times New Roman", Font.PLAIN, 100);
Font normalFont = new Font("Times New Roman", Font.PLAIN, 30);
public static String playerName;
public static String weapon,position;
public static int playerHP;
public static int weaponDamage;
public static void main(String[] args)
{
new Game();
}
public Game()
{
window = new JFrame();
window.setSize(1440,900);
window.setTitle("W: " + window.getWidth() + " H: " + window.getHeight());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().setBackground(Color.black);
window.setLayout(new GridBagLayout());
con = window.getContentPane();
//Panels are used to make sections in the window (Background)
//Labels are used to write in the sections/panels (Foreground)
//Buttons can be pressed inside Panels
//To make a text you need to design a panel, design its size/color,
//Design its text the same way, then add it to the panel
titlePanel = new JPanel();
titlePanel.setBounds(100, 100, 1080 , 150);
titlePanel.setBackground(Color.black);
titleLabel = new JLabel("Adventure");
titleLabel.setForeground(Color.white);
titleLabel.setFont(titleFont);
startPanel = new JPanel();
startPanel.setBounds(540, 600, 200, 100);
startPanel.setBackground(Color.black);
startButton = new JButton("START");
startButton.setBackground(Color.black);
startButton.setForeground(Color.white);
startButton.setFont(normalFont);
startButton.addActionListener(tsHandler);
window.addComponentListener(compHandler);
titlePanel.add(titleLabel);
startPanel.add(startButton);
con.add(titlePanel, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
con.add(startPanel, gbc);
window.setVisible(true);
}
public void createGameScreen()
{
titlePanel.setVisible(false);
startButton.setVisible(false);
mainTextPanel = new JPanel();
//mainTextPanel.setBounds(100, 100, 1080, 250);
mainTextPanel.setBackground(Color.black);
mainTextPanel.setBorder(whiteline);
mainTextArea = new JTextArea("This is the main text area");
mainTextArea.setBounds(100,100,1080,250);
mainTextArea.setBackground(Color.black);
mainTextArea.setForeground(Color.white);
mainTextArea.setLayout(new GridLayout());
mainTextArea.setFont(normalFont);
mainTextArea.setLineWrap(true);
mainTextArea.setWrapStyleWord(true);
playerPanel = new JPanel();
playerPanel.setBounds(100, 100, 1080, 50);
playerPanel.setBackground(Color.blue);
playerPanel.setLayout(new GridLayout(1,4));
choiceButtonPanel = new JPanel();
choiceButtonPanel.setBounds(500, 350, 300, 250);
choiceButtonPanel.setLayout(new GridLayout(2,4, 50, 50));
choiceButtonPanel.setBackground(Color.red);
choice1 = new JButton("Choice 1");
choice1.setBackground(Color.black);
choice1.setForeground(Color.white);
choice1.setFont(normalFont);
choice1.setFocusPainted(false);
choice1.addActionListener(choiceHandler);
choice1.setActionCommand("c1");
choiceButtonPanel.add(choice1);
choice2 = new JButton("Choice 2");
choice2.setBackground(Color.black);
choice2.setForeground(Color.white);
choice2.setFont(normalFont);
choice2.setFocusPainted(false);
choice2.addActionListener(choiceHandler);
choice2.setActionCommand("c2");
choiceButtonPanel.add(choice2);
choice3 = new JButton("Choice 3");
choice3.setBackground(Color.black);
choice3.setForeground(Color.white);
choice3.setFont(normalFont);
choice3.setFocusPainted(false);
choice3.addActionListener(choiceHandler);
choice3.setActionCommand("c3");
choiceButtonPanel.add(choice3);
choice4 = new JButton("Choice 4");
choice4.setBackground(Color.black);
choice4.setForeground(Color.white);
choice4.setFont(normalFont);
choice4.setFocusPainted(false);
choice4.addActionListener(choiceHandler);
choice4.setActionCommand("c4");
choiceButtonPanel.add(choice4);
choice5 = new JButton("Choice 5");
choice5.setBackground(Color.black);
choice5.setForeground(Color.white);
choice5.setFont(normalFont);
choice5.setFocusPainted(false);
choice5.addActionListener(choiceHandler);
choice5.setActionCommand("c5");
choiceButtonPanel.add(choice5);
choice6 = new JButton("Choice 6");
choice6.setBackground(Color.black);
choice6.setForeground(Color.white);
choice6.setFont(normalFont);
choice6.setFocusPainted(false);
choice6.addActionListener(choiceHandler);
choice6.setActionCommand("c6");
choiceButtonPanel.add(choice6);
choice7 = new JButton("Choice 7");
choice7.setBackground(Color.black);
choice7.setForeground(Color.white);
choice7.setFont(normalFont);
choice7.setFocusPainted(false);
choice7.addActionListener(choiceHandler);
choice7.setActionCommand("c7");
choiceButtonPanel.add(choice7);
choice8 = new JButton("Choice 8");
choice8.setBackground(Color.black);
choice8.setForeground(Color.white);
choice8.setFont(normalFont);
choice8.setFocusPainted(false);
choice8.addActionListener(choiceHandler);
choice8.setActionCommand("c8");
choiceButtonPanel.add(choice8);
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
con.add(playerPanel,gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
//gbc.ipadx = 750;
gbc.ipady = 1000;
gbc.gridwidth = 2;
gbc.gridx = 1;
gbc.gridy = 0;
con.add(mainTextPanel,gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.gridx = 1;
gbc.gridy = 5;
con.add(choiceButtonPanel,gbc);
hpLabel = new JLabel("HP: ");
hpLabel.setFont(normalFont);
hpLabel.setForeground(Color.white);
hpLabelNumber = new JLabel();
hpLabelNumber.setFont(normalFont);
hpLabelNumber.setForeground(Color.white);
weaponLabel = new JLabel("Weapon: ");
weaponLabel.setFont(normalFont);
weaponLabel.setForeground(Color.white);
weaponLabelName = new JLabel();
weaponLabelName.setFont(normalFont);
weaponLabelName.setForeground(Color.white);
playerPanel.add(hpLabel);
playerPanel.add(hpLabelNumber);
playerPanel.add(weaponLabel);
playerPanel.add(weaponLabelName);
mainTextPanel.add(mainTextArea, BorderLayout.PAGE_START);
playerSetup();
}
public void playerSetup()
{
playerHP = 15;
weapon = "Fists";
weaponLabelName.setText(weapon);
hpLabelNumber.setText("" + playerHP);
ForestEvents.townGate();
}
/*public void townGate()
{
position = "towngate";
mainTextArea.setText("You are at the gates of the town. A guard is standing in front of you. What do you do?");
choice1.setText("Talk to the Guard");
choice2.setText("Attack the Guard");
choice3.setText("Leave");
choice4.setText("");
}*/
public void talkGuard()
{
position = "talkguard";
mainTextArea.setText("Guard: Hello Stranger. I have never seen you before. I'm sorry but I cannot let you enter.");
choice1.setText("Go Back");
choice2.setText("");
choice3.setText("");
choice4.setText("");
}
public void attackGuard()
{
position = "attackguard";
mainTextArea.setText("Guard: HOW DARE YOU!\nThe guard fought back and hit you hard.\n(You received 3 damage)");
playerHP -= 3;
hpLabelNumber.setText("" + playerHP);
choice1.setText("Go Back");
choice2.setText("");
choice3.setText("");
choice4.setText("");
}
public void crossRoad()
{
position = "crossroads";
mainTextArea.setText("You are at the crossroad.\n Go south to go back to the town.");
choice1.setText("Go North");
choice2.setText("Go East");
choice3.setText("Go South");
choice4.setText("Go West");
}
public class ComponentHandler implements ComponentListener
{
public void componentResized(ComponentEvent e)
{
Component c = (Component)e.getSource();
window.setTitle("W: " + c.getWidth() + " H: " + c.getHeight());
}
#Override
public void componentHidden(ComponentEvent e)
{
// TODO Auto-generated method stub
}
#Override
public void componentMoved(ComponentEvent e)
{
}
#Override
public void componentShown(ComponentEvent e)
{
}
}
public class TitleScreenHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
createGameScreen();
}
}
public class ChoiceHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String yourChoice = event.getActionCommand();
switch (position)
{
case "towngate":
switch(yourChoice)
{
case "c1":
talkGuard();
break;
case "c2":
attackGuard();
break;
case "c3":
crossRoad();
break;
case "c4":
break;
}
break;
case "talkguard":
switch(yourChoice)
{
case "c1":
ForestEvents.townGate();
break;
}
break;
case "attackguard":
switch(yourChoice)
{
case "c1":
ForestEvents.townGate();
break;
}
break;
case "crossroad":
switch(yourChoice)
{
case"c1":
break;
case"c2":
break;
case"c3":
ForestEvents.townGate();
break;
case"c4":
break;
}
break;
}
}
}
}
Edit: Added the rest of the code and added the textarea to the scrollpane and the scrollpane to the Jpanel now the text isnt showing up in the panel.
import javax.swing.JTextArea;
public class ForestEvents
{
String pos;
int hp;
public ForestEvents()
{
pos = Game.position;
hp = Game.playerHP;
}
public static void townGate()
{
Game.position = "towngate";
Game.mainTextArea.setText("You are at the gates of the town. A guard is standing in front of you. What do you do? \na\nas\n\n\n\n\\n"
+ "\n\n\n\1\n1\n\n\n\n\n\\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n1\n1\n2\n2\n3\n4\n6");
Game.choice1.setText("Talk to the Guard");
Game.choice2.setText("Attack the Guard");
Game.choice3.setText("Leave");
Game.choice4.setText("");
}
}
You will want to get your JTextArea into JScrollPane, as Adeel said in the comments (+1), then control it with GridBagLayout. No need to set component bounds, preferred size etc. If you want to use GridBagLayout, you have to learn how weights work with fill and anchor. In code below change gbc.fill HORIZONTAL to VERTICAL and swap weights I used for adding scroll to window (so it should be weightx=0,y=1), or change fill to BOTH and make both weights equal to 1 (in this case, you can comment out this empty JLabel I added at the end). Observe and learn.
In your code, you're not setting weights. So, as you may have guessed, everything has the same weight. mainTextArea is added while gbc.fill is HORIZONTAL, no weights and is not inside JScrollPane - that's why it stretches. And be careful with ipads.
SSCCE (comments in code)
public class DontStretchMyTextArea {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setSize(1440, 900);
window.setTitle("W: " + window.getWidth() + " H: " + window.getHeight());
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTH;
gbc.insets = new Insets(10, 10, 10, 10);
JTextArea mainTextArea = new JTextArea( "This is the main text area" , 10 , 30 ); //here you can set how many rows/columns you want,
//but anyway GridBagLayout will recalculate size of component
//based on gbc.fill, weights and surrounding components
//mainTextArea.setLayout(new GridLayout());
mainTextArea.setLineWrap(true);
mainTextArea.setWrapStyleWord(true);
JScrollPane scroll = new JScrollPane(mainTextArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints panelGBC = new GridBagConstraints();
panelGBC.weightx = 1; //I want to fill whole panel with JTextArea
panelGBC.weighty = 1; //so both weights =1
panelGBC.fill = GridBagConstraints.BOTH; //and fill is set to BOTH
panel.add(scroll, panelGBC);
panel.setBackground(Color.gray);//this shouldn't be visible
gbc.weightx = 1;
gbc.weighty = 0;
window.add(panel, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridx++;
window.add(new JLabel(), gbc); //GridBagLayout always needs component with both weights =1
SwingUtilities.invokeLater(() -> { //we get our frame on EDT
window.pack();
window.setVisible(true);
});
}
}
How to use GridBagLayout
You can also add scroll directly to window. panel was created just for illustration purposes.

How to open another program with for statements 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.

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