Code Executing in different orders, Jframe, Button and TextArea - java

Basically i have some code to make an interface that allows me to submit a request and it pulls the necessary information from a txt File. For some reason wheni execute my StartUp for the code, sometimes the button isnt there, one text box dominates the screen, all the textboxes overlap... Its weird.
Anyway heres the GUI Code
public class Menu {
SubmitCode submit = new SubmitCode();
public static JFrame frame;
public static JTextField field;
public static Button btn;
public static TextArea txtComm;
public static TextArea txtSites;
public static TextArea txtProg;
public static Dimension dim = new Dimension(40, 10);
public Menu() {
frame = new JFrame();
frame.setTitle("Welcome :)");
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void open() {
Menu.main(null); // Opens up the main method of the class
}
public static void main(String args[]) {
field = new JTextField();
btn = new Button();
txtComm = new TextArea();
txtSites = new TextArea();
txtProg = new TextArea();
field.setText("What do you want to do?");
field.setSize(390, 20);
field.setLocation(0, 125);
btn.setVisible(true);
btn.setLabel("Click to Submit");
btn.setSize(90, 20);
btn.setLocation(400, 125);
txtComm.setVisible(true);
txtComm.setText("Commands: ");
txtComm.setSize(150, 100);
txtComm.setLocation(10, 10);
txtComm.setEditable(false);
frame.add(txtComm);
txtSites.setVisible(true);
txtSites.setText("Sites: ");
txtSites.setSize(150, 100);
txtSites.setLocation(170, 10);
txtSites.setEditable(false);
frame.add(txtSites);
txtProg.setVisible(true);
txtProg.setText("Programmes: ");
txtProg.setSize(150, 100);
txtProg.setLocation(330, 10);
txtProg.setEditable(false);
frame.add(txtProg);
frame.setSize(500, 175);
frame.add(field, BorderLayout.SOUTH);
frame.add(btn);
btn.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Do Something Clicked");
SubmitCode.main(null);
}
});
}
}

Suggestions:
Don't use static methods/fields, except when a specific need arises or for the main method. You do not have the need here.
Instead use valid classes, classes with constructors, instance (non-static) fields and instance methods.
Don't needlessly mix AWT and Swing components but instead use just Swing components. So JTextArea, not TextArea, JButton, not Button, etc....
For instance, your Menu constructor is wasted code that is never called due to your misuse and over-use of statics.
Don't set sizes, use null layouts and absolute positioning such as with setBounds.
Instead read up on and use the layout managers.
Don't pepper your code with useless bits such as most of your calls to setVisible(true).
Call setVisible(true) on the top level window, here your JFrame, after adding all components.
Do read the relevant tutorials as this is all very well explained there. Google Java Swing Tutorials and check the very first hit.
This bit scares me: SubmitCode.main(null); and suggests that you're trying to call the static main method of another class from within a GUI. You should avoid doing this, and instead have your SubmitCode class use good OOP techniques including non-static methods and fields, constructors, etc...

Related

JPanel changes shape/position within JFrame when JButton is pressed. Why?

Basically, I have added a JPanel to a JFrame, and whenever I press the button within the JPanel (which changes the visibility of a component within the JPanel), the size of the JPanel and the location of the components change. I cant for the life of me figure out why this problem is occurring. Any help is greatly appreciated.
Google Searches
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Main {
private JFrame window;
private JPanel loginPanel;
private JButton loginButton;
private JTextField usernameField;
private JPasswordField passwordField;
private JLabel usernameLabel, passwordLabel, errorMessage;
public static void main(String[] args) {
Main program = new Main();
}
public Main() {
createWindow();
runProgram();
}
private void createWindow() {
window = new JFrame("Dentist Program");
window.setSize(1450, 900);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loginPanel = new JPanel();
loginPanel.setSize(300, 400);
loginPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
usernameLabel = new JLabel("Username");
usernameLabel.setSize(125, 20);
usernameLabel.setLocation(loginPanel.getWidth()/2 - usernameLabel.getWidth()/2, 100);
usernameField = new JTextField();
usernameField.setSize(125, 25);
usernameField.setLocation(loginPanel.getWidth()/2 - usernameField.getWidth()/2, usernameLabel.getY() + usernameLabel.getHeight());
passwordLabel = new JLabel("Password");
passwordLabel.setSize(125, 20);
passwordLabel.setLocation(loginPanel.getWidth()/2 - passwordLabel.getWidth()/2, usernameField.getY() + usernameField.getHeight() + 10);
passwordField = new JPasswordField();
passwordField.setSize(125, 25);
passwordField.setLocation(loginPanel.getWidth()/2 - passwordField.getWidth()/2, passwordLabel.getY() + passwordLabel.getHeight());
loginButton = new JButton("Log In");
loginButton.setSize(80, 25);
loginButton.setLocation(passwordField.getX(), passwordField.getY() + passwordField.getHeight() + 15);
loginButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0) {
errorMessage.setText("");
loginPanel.repaint();
}
});
errorMessage = new JLabel("Username and/or password is incorrect");
errorMessage.setSize(250, 25);
errorMessage.setLocation(loginPanel.getWidth()/2 - errorMessage.getWidth()/2, loginButton.getY() + loginButton.getHeight() + 25);
errorMessage.setForeground(Color.RED);
loginPanel.add(usernameLabel);
loginPanel.add(usernameField);
loginPanel.add(passwordLabel);
loginPanel.add(passwordField);
loginPanel.add(loginButton);
loginPanel.add(errorMessage);
window.getContentPane().add(loginPanel);
window.repaint();
}
private void runProgram() {
}
}
The reason your UI changes is because the look that you think is correct (the initial look) is actually wrong, and the resized version is the "correct" version.
Typically, you'd call pack() after adding components to a container, which tries to display the contents of that container at their preferred sizes. To see the correct UI before and after the button press, following your call to repaint(), add:
window.pack();
You may think that looks terrible (which it does) but it's exactly what your code is asking for, and is therefore the "correct" version.
Take note that you are trying to set sizes with explicit calls to setSize(), which is a bad practice in Swing. At most, you should be setting preferred sizes and letting the layout manager handle the details. When you try to micromanage component sizes and locations, you can often make it look good on one platform, but irredeemably bad on others. Remember that Java is supposed to be the "write once, run anywhere" language.
When you want more control over your layout, you should explicitly specify and use a layout manager, rather than just accepting the default layout. In almost every non-trivial UI, GridBagLayout is your best bet.
Finally, you don't need to explicitly call repaint() on your UI when something changes. Typically, you'd call paint() and repaint() when you are working with graphics. Let Swing handle the painting automatically.

How can I make Eclipse WindowBuilder parse an inherited JFrame?

I have a class BaseWindow with a JFrame mainFrame, and a bunch of methods that work on mainFrame. Actual windows in my app are made by extending BaseWindow.
The class extending BaseWindow inherits mainFrame, and that somehow prevents window builder from "seeing" it when it parses the code. All I see in window builder's design tab is an empty window, but when I run the code everything works fine.
How can I make this approach work with window builder, or "trick" window builder into parsing mainFrame? Here is an example class extending BaseWindow:
package GUIApp;
//took out the imports to save space
class SampleWindowOne extends BaseWindow{
public JLabel txtSampleText;
public JButton btnMagicButton;
public SampleWindowOne() {
initialize();
}
public void run(){
mainFrame.setBounds(getCenteredBounds());
mainFrame.setVisible(true);
}
private void initialize() {
mainFrame = new JFrame();
mainFrame.setBounds(100,100,700,525);
mainFrame.setTitle("Sample Window One");
mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mainFrame.getContentPane().setLayout(null);
txtSampleText = new JLabel();
txtSampleText.setFont(new Font("Dialog", Font.PLAIN, 25));
txtSampleText.setHorizontalAlignment(SwingConstants.CENTER);
txtSampleText.setText("Sample Window");
txtSampleText.setBounds(12, 50, 674, 51);
mainFrame.getContentPane().add(txtSampleText);
JTextArea txtrLoremIpsumDolor = new JTextArea();
txtrLoremIpsumDolor.setEditable(false);
txtrLoremIpsumDolor.setFont(new Font("Dialog", Font.PLAIN, 16));
txtrLoremIpsumDolor.setForeground(Color.DARK_GRAY);
txtrLoremIpsumDolor.setWrapStyleWord(true);
txtrLoremIpsumDolor.setLineWrap(true);
txtrLoremIpsumDolor.setText("Lorem ipsum dolor sit amet...");
txtrLoremIpsumDolor.setBounds(57, 131, 609, 296);
mainFrame.getContentPane().add(txtrLoremIpsumDolor);
btnMagicButton = new JButton("End Program");
btnMagicButton.setEnabled(false);
btnMagicButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
requestTerminate();
}
});
btnMagicButton.setBounds(257, 451, 175, 25);
mainFrame.getContentPane().add(btnMagicButton);
}
}
I'm sure you're past that now, but for others searching solution to this:
In eclipse go to:
Window -> Preferences -> Window Builder(tree) -> Swing -> Code Generation
Set initGUI method from the combo box of "Method name for new statements" at the top of the page. (you can also try to set another method name)
In "Variable generation" section, click once on third tab: "Init. Field" so that you can see its' square filled with v sign(and the other tabs have an empty square).
Click ok.
Restart eclipse.
Create a method named initGUI as follows:
private void initGUI() {
}
Copy all your code from the constructor to that method.
Call that method from your constructor:
public WindowTest()
{
initGUI();
}
Go to window builder design by clicking: "Design" at the bottom of the editor.
Click a lot of reparse if necessary.
Now add one component (JButton for instance) to the window, and watch it go into iniGUI method. Once you've seen that happens - it is safe to take out code lines that are not realted to GUI from that method and put them in the constructor if you want.
Okay, I found a way to trick window builder into working! I changed the constructor from:
public SampleWindowOne() {
initialize();
}
to:
public SampleWindowOne() {
JFrame mainFrame;
initialize();
}
Hopefully this helps someone with their own code.
Edit: not fully solved after all, see below. I will update if I find a better solution.
Edit2: Okay, after a good night's sleep the solution is pretty obvious. I now declare a separate JFrame at the beginning of the class. I add all my elements to this frame instead of mainFrame, and at the end of initialize I put
mainFrame = newFrame;

How do I validate a textfield in java

public class Login extends JFrame{
JFrame frame; //frame
JTextField field; //to get username
JPasswordField p; //password field
JLabel l; //used for printing on frame
JButton b;
Login() {
frame = new JFrame("Login");
frame.setSize(350,200);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
l = new JLabel("Enter Username");
l.setLocation(10,10);
l.setSize(l.getPreferredSize());
frame.add(l);
field = new JTextField();
field.setColumns(15);
field.setSize(field.getPreferredSize());
field.setLocation(120,10);
frame.add(field);
l = new JLabel("Enter Password");
l.setLocation(10,40);
l.setSize(l.getPreferredSize());
frame.add(l);
p = new JPasswordField();
p.setColumns(15);
p.setSize(p.getPreferredSize());
p.setLocation(120,40);
frame.add(p);
b = new JButton("OK");
b.setSize(b.getPreferredSize());
b.setLocation(120, 80);
frame.add(b);
frame.setVisible(true);
}
private class b implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String str;
str = field.getText();
if(str.equals("")) {
JOptionPane.showMessageDialog(null,"Please enter username");
field.requestFocusInWindow();
} else {
}
}
}
public static void main (String[] args) {
new Login();
}
}
the button won't functioning when I'm hit it
the button won't functioning when I'm hit it
You need to add the ActionListener to the button:
b = new JButton("OK");
b.addActionListener( new b() );
Make your class names more descriptive. "b" is not descriptive. Also, class names should start with an upper case character.
Don't use null layouts and setBounds(...). Swing was designed to be used with Layout Managers. Keep a link to the tutorial handy for Swing basics.
Take a look at How to Write an Action Listeners and How to Use Buttons, Check Boxes, and Radio Buttons.
Basically, you never register the ActionListener with your JButton
b.addActionListener(new b());
You code would be easier to read if you used meaningful variable names and followed the establishing coding conventions of the language. Have a look at Code Conventions for the Java TM Programming Language, for more details, it will make it easier for people to read your code and for you to read others
You may also want to have a read of You might want to have a read of Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?, but since you're discarded the layout manager, the use of setPreferredSize is completely pointless.
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

How do I create 2 frames in Java and Link them together?

I just created a GUI, now I want to create another GUI and link both together.
So on the first GUI when the user selects 'next' button, the second GUI is displayed.
For this, do I have to create a new class and just create a GUI again?
Here is what I have now:
import java.awt.Color;
import javax.swing.*;
public class Wizard {
private JLabel lblPicture;
private JRadioButton btLdap, btKerbegos, btSpnego, btSaml2;
private JButton btNext;
private JPanel panel;
public static void main(String[] args) {
new Wizard();
}
public Wizard() {
JFrame frame = new JFrame("Wizard");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,360);
frame.setVisible(true);
MyPanel();
RadioButtons();
Button();
Image();
groupButton();
frame.add(panel);
frame.setVisible(true);
}
public void MyPanel() {
panel = new JPanel();
panel.setLayout(null);}
public void RadioButtons() {
btLdap = new JRadioButton ("Ldap");
btLdap.setBounds(60,85,100,20);
panel.add(btLdap);
btKerbegos = new JRadioButton ("Kerbegos");
btKerbegos.setBounds(60,115,100,20);
panel.add(btKerbegos);
btSpnego =new JRadioButton("Spnego");
btSpnego.setBounds(60,145,100,20);
panel.add(btSpnego);
btSaml2 = new JRadioButton("Saml2");
btSaml2.setBounds(60,175,100,20);
panel.add(btSaml2);
}
public void Button() {
btNext = new JButton ("Next");
btNext.setBounds(400,260,100,20);
panel.add(btNext);
}
public void Image() {
ImageIcon image = new ImageIcon("image.jpg");
lblPicture = new JLabel(image);
lblPicture.setBounds(200,20, 330, 270);
panel.add(lblPicture);
}
private void groupButton() {
ButtonGroup bg1 = new ButtonGroup( );
bg1.add(btLdap);
bg1.add(btKerbegos);
bg1.add(btSpnego);
bg1.add(btSaml2);
}
}
To display another window, you would create the window, be it a JFrame, JDialog, or what have you, and call setVisible(true) just like you do for your first window.
You ask if your other "window" should be in another class, and likely that answer is yes. Since it will have a completely different set of behaviors and goals from the first class, better to separate out concerns.
Having said that, what you plan to do, to show multiple windows is not always the best user interface design. Better often is to show multiple views using a container that uses a CardLayout.
If you want to display another window in a modal fashion, that is, have the first window wait for the second window to be processed before allowing user interaction, the second window should be a modal JDialog or JOptionPane (a JDialog in disguise).
I think for what you want to achieve, the use of a CardLayout would be appropriate.
This enables you to have multiple panels within the one frame with only one panel visible at a time and has functionality to 'flip' through the panels like a 'deck of cards'. So on initialising your frame you create the panels you want, and specify which one to start at then your next button will go to the next panel in the list.
See the tutorial here there are also some video tutorials available on youtube.
Write the two GUI's in different classes. When you start your program, start the first GUI.
FirstGUI frame1 = new FirstGUI("Title text");
frame1.setVisible(true);
Then, in the action listener code for the button you call "next"...
frame1.setVisible(false); //if you want to save the frame
frame1.dispose(); //if you want to kill the frame
SecondGUI frame2 = new SecondGUI("Title text");
frame2.setVisible(true);

Controlling another class from a different class

I am having a bit of problem regarding Swing. I have a JFrame called FrameMain. Inside it is a JPanel called panelChoices.
When FrameMain is called/created, it fills up the panelChoices object with a number of PanelEntries objects, which is a JPanel with a number of JButtons in it (it is a different class that I wrote).
What I want to do is when I click one of the buttons inside the PanelEntries object, I want to destroy/remove FrameMain, along with the rest of it components (including the PanelEntries object that contains the JButton).
I've tried using super but it returns the JPanel (the PanelEntries object) that holds the JButton and not FrameMain that holds them all together. How can I achieve this?
EDIT: It seems that I am not clear enough, so here's a bit more information from my work. I don't have the actual code right now because I am on a different machine but I hope this will help elaborate my question.
public class FrameMain() {
private JFrame frameMain;
private JPanel panelChoices;
public FrameMain(args) {
createGUI();
loadData();
}
private void createGUI() {
JFrame frameMain = new JFrame();
JPanel panelChoices = new JPanel(new GridLayout(1,1));
frameMain.add(panel);
// removed formatting and other design codes since they are not important.
pack();
}
private void loadData() {
boolean available;
for (int i = 1; i <= 10; i++) {
// do some if/else and give value to boolean available
PanelEntries panel = new PanelEntries(i, available);
frameMain.add(panel);
// more code here to handle data.
}
}
}
public class PanelEntries() extends JPanel {
public PanelEntries(int num, boolean avb) {
JButton button = new JButton("Button Number " + num);
button.setEnabled(avb);
add(button);
// add action listener to created button so that it calls 'nextScreen()' when clicked.
// more code
pack();
}
private void nextScreen() {
// destroy/dispose MainFrame here.
// See Notes.
AnotherFrame anotherFrame = new AnotherFrame();
}
}
Notes:
All classes are inside their own .java file.
I need to know how to dispose FrameMain from the button inside the PanelEntries object, not just disposing a JFrame.
As per the given information,
If you want to exit the application, its not a big deal use System.exit(0); :)
If you mean to dispose the frame, jframe.dispose();
If you want to remove a componet / all components you can use .remove(Component) / .removeAll() etc
If this did not help, please re-write your question with more information.

Categories

Resources