I am trying to have a textfield and graphics in the same jframe but it is not working properly. I want to have the textfield in the bottom and the rest of the jframe for the graphics instead when I run it the textfield acts weirdly and covers up the entire area. Does anybody know how I can get it to work how I want it?
package pack;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class gui extends JPanel implements Runnable{
Thread t = new Thread(this);
protected JTextField textField;
private final static String newline = "\n";
public int x;
public int y;
public static void main(String args[])
{
new gui();
new input();
}
public void input()
{
textField = new JTextField(20);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridwidth = 500;
c.gridheight = 100;
c.fill = GridBagConstraints.HORIZONTAL;
add(textField, c);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
}
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
textField.selectAll();
}
public gui()
{
textField = new JTextField(20);
JFrame f = new JFrame("lol");
System.out.println("::");
f.setTitle("Basic window");
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.add(this);
f.setVisible(true);
f.setFocusable(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(textField);
run();
}
public void run()
{
while(true)
{
try
{
t.sleep(10);
}
catch(Exception e){}
System.out.println(":D");
x++;
y++;
repaint();
}
}
public void paint (Graphics g)
{
g.setColor(Color.red);
}
}
Delete this class and start fresh with a new class. The structure of the code is wrong , the class names are wrong, the custom painting is wrong, the use of Threads is wrong, the new input() doesn't do anything, you should not be using Thread.sleep(), you should not override paint(), you should not add a component to the frame after the frame is visible.
Start by reading the section from the Swing tutorial on Custom Painting. There you will find a working example that will show you how to better structure you class when doing custom painting. Use this demo code as the starting point for your program and make changes (one at a time) to this working code.
Then you can change that code and add a JTextField to the frame. You will also need to read the Swing tutorial on Using Layout Managers, to understand how a BorderLayout works. So start with something simple that works and then add extra components. Don't try to do it all at one time.
Things that you are doing in wrong way.
JFrame by default has uses BorderLayout and you are adding two components in the center hence only last components are visible.
You are adding JTextField inside JFrame as well as JPanel. Don't know why?
Use BorderLayout.SOUTH to add the JTextField in the south and don't add it into JPanel as shown below:
public gui() {
...
textField = new JTextField(20);
JFrame f = new JFrame("lol");
f.add(this);
f.add(textField, BorderLayout.SOUTH);
...
}
Please read below post once again.
How to Use GridLayout
How to Use GridBagLayout
Related
I am trying to create a GUI using Java Swing, and am having a problem using the pack() method. As you can see, I create and add all of the elements to the frame in the createTitleText() method and the createBoxes() method. Only after those two methods are called do I call the pack() method, yet when I run the program, I get a small GUI with the close and minimize buttons. But if I expand it, it shows me the proper layout.
The only cause for such a problem that I have found online would be that I call pack() before adding all of my elements to the frame, but that is not the case. How can I fix this?
By the way, if it wasn't clear, I am trying to not use the setSize() method on the frame, and make it so that the frame's size fits the contents of the elements added to it.
import javax.swing.*;
import java.awt.*;
public class Frame extends JFrame {
private LetterBox[][] boxes;
public Frame() {
boxes = new LetterBox[6][5];
// frame styling
setTitle("My Frame");
getContentPane().setBackground(new Color(0x121213));
createTitleText();
createBoxes();
// boilerplate frame configuration
setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
pack();
}
public void createTitleText() {
JLabel label = new JLabel("Test");
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.TOP);
label.setBounds(0, 0, 400, 100);
label.setForeground(Color.WHITE);
label.setFont(new Font("Arial", Font.BOLD, 36));
add(label);
}
public void createBoxes() {
for (int r = 0; r < 6; r++) {
for (int c = 0; c < 5; c++) {
LetterBox box = new LetterBox();
boxes[r][c] = box;
box.setLetter(r + " " + c);
add(box.getBox()); // box.getBox() returns a JLabel
}
}
}
public static void main(String[] args) {
new Frame();
}
}
I am stumped and desperate for help. Been able to figure everything else out until I got into GUI's. What I am trying to do is go from the LogInPane (Log In Page) to JobSelectionGUI (Job Selection Page);
When I compile it runs how I want it to, but I can't figure out how to get my JFrame from LogInPaneGUI to close when it opens JobSelectionGUI, Tons of reading and videos and picking GUI's/Applying them is rough! I started with a GridLayout then switched to GridBagLAyout, then tried CardLayout and now back to GBL.
I don't use an IDE; I use SublimeText, so if something looks extremely elongated in my code, its because I had to write it out long for Sublime (or because I'm bad). All my code is separated into different classes so it stays neat and easy to debug. Every class has its own package, and every package has no more than 2 Methods. I work my butt off to keep my main completely empty!
Taking all criticism and advice!
MAIN:
package com.hallquist.kurtis.leigh.srcmain;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.text.*;
// Class imports;
import JobSelection.*;
import LogInPane.*;
// My Main function. Used to pull packages and methods and compile them here;
public class SrcMainUserInformation{
public static void main(String[] args){
LogInPaneGUI logInGUI = new LogInPaneGUI();
logInGUI.logInPaneMainGUI();
}
}
First Class:
package LogInPane; // package name;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import JobSelection.*; //import for next GUI when LogInButton is clicked;
public class LogInPaneGUI{
private static final JFrame frame = new JFrame();
private static final int COLS = 10; // Max columns;
private static final JPanel panelForm = new JPanel(new GridBagLayout()); // layout
private static final JTextField fieldLogInName = new JTextField(COLS); //login
private static final JPasswordField logInPassword = new JPasswordField(COLS); //pw
private static final JButton logInButton = new JButton("Log In"); //login button
private static final JButton exitButton = new JButton("EXIT"); //system.exit button
private static final JButton newUser = new JButton("New User? Click here to sign up!"); // new user button
// Wigits on login page;
public LogInPaneGUI(){
GridBagConstraints c = new GridBagConstraints();
// Creates the panel that goes ontop of the JFrame;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.LINE_END;
panelForm.add(new JLabel("Account Name: "), c);
c.gridy ++;
panelForm.add(new JLabel("Password: "), c);
c.gridy ++;
c.gridx = 1;
c.gridy = 0;
c.anchor = GridBagConstraints.LINE_START;
panelForm.add(fieldLogInName, c);
c.gridy++;
panelForm.add(logInPassword, c);
c.gridy++;
panelForm.add(logInButton, c);
c.gridy++;
panelForm.add(newUser, c);
c.gridy++;
panelForm.add(exitButton, c);
// Goes to fourm/website on newUser click;
newUser.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("Fourm/Website to sign up for game");
}
});
// Exits program on exitButton click;
exitButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
// Goes to JobSelectionGUI on logInButton Click;
logInButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
JobSelectionGUI jobSelecting = new JobSelectionGUI();
jobSelecting.jobSelectionJFrameGUI();
// frame.dispose();
// System.out.println("Will log you in when I set it up");
}
});
}
// Actual JFrame that everything goes ontop of;
public static void logInPaneMainGUI(){
JFrame frame = new JFrame("FirstProject");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1080, 720);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(panelForm);
}
}
Second Class:
package JobSelection;
import java.awt.*;
import java.awt.event.ActionEvent.*;
import javax.swing.*;
import javax.swing.text.*;
// Mass import from JobSelection package; All base job information;
import JobSelection.JobInformationIndex.JobAmazonData.*;
import JobSelection.JobInformationIndex.JobBanditData.*;
import JobSelection.JobInformationIndex.JobLancerData.*;
import JobSelection.JobInformationIndex.JobSorcererData.*;
import JobSelection.JobInformationIndex.JobWitchData.*;
import LogInPane.*; // to return to login screen;
import JobSelection.*; // dont know if needed;
public class JobSelectionGUI{
private static JFrame frame = new JFrame();
private static JSplitPane jSplitPane = new JSplitPane();
private static JPanel leftPane = new JPanel();
private static JLabel logInCharacterName = new JLabel();
private static JTextField userCharacterName = new JTextField();
private static JButton logInAccept = new JButton("Accept");
private static JButton logInBack = new JButton("Back");
private static JTextArea firstGameIntroduction = new JTextArea();
private static JTextArea descriptionIntroduction = new JTextArea();
private static JTextArea jobSelectedInformation = new JTextArea();
private static JPanel allWidgits = new JPanel();
public JobSelectionGUI(){
JTextArea firstGameIntroduction = new JTextArea("\ Text.");
firstGameIntroduction.setLineWrap(true);
firstGameIntroduction.setWrapStyleWord(true);
JScrollPane areaScrollPane = new JScrollPane(firstGameIntroduction);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(250, 250));
areaScrollPane.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Introduction"),
BorderFactory.createEmptyBorder(5,5,5,5)),
areaScrollPane.getBorder()));
leftPane.add(areaScrollPane);
JTextArea descriptionIntroduction = new JTextArea(" Text.\n");
descriptionIntroduction.setLineWrap(true);
descriptionIntroduction.setWrapStyleWord(true);
JScrollPane areaScrollPaneTwo = new JScrollPane(descriptionIntroduction);
areaScrollPaneTwo.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPaneTwo.setPreferredSize(new Dimension(250, 250));
areaScrollPaneTwo.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("What to expect"),
BorderFactory.createEmptyBorder(5,5,5,5)),
areaScrollPaneTwo.getBorder()));
leftPane.add(areaScrollPaneTwo);
}
public static void jobSelectionJFrameGUI(){
JFrame frame = new JFrame("FirstProject");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1080, 720);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(leftPane);
}
}
You grossly overuse the static modifier and most of your fields should not in fact be static. I would venture to state that most if not all of your class's fields should be private instance fields.
The log-in window should not be a JFrame but rather a blocking or "modal" dialog, and for Swing that means using a modal JDialog or JOptionPane (which creates a modal JDialog behind the scenes)
A modal dialog will block the calling code when it is displayed
And if the dialog is modal, then you know when it is no longer visible since the calling code is unblocked. This is when you would query the state of the dialog's fields (using public getter methods, not calling static fields directly), and decide if the login was successful or not. If so, show your main GUI window or JFrame.
Another option is to yes, use CardLayout, but for this to work, all your major GUI classes should be geared towards creating JPanels, not JFrames. This way you can insert the panels where and when needed, including within top-level windows such as JFrames or JDialogs, within or JPanels, or swapped using a CardLayout.
Note that frame.dispose() isn't working for you because you shadow the frame field by re-declaring it logInPaneMainGUI() method.
public static void logInPaneMainGUI() {
// ***** this creates a new local JFrame variable called frame
JFrame frame = new JFrame("FirstProject");
// so calling frame.dispose() elsewhere will have no effect on this window
Don't do this, and the .dispose() method call will close the first window.
public static void logInPaneMainGUI() {
frame = new JFrame("FirstProject"); // this initializes the frame field
// so calling frame.dispose() elsewhere will have no effect on this window
Of course frame would have to be non-final or not-initialized previously. I still would recommend using a JDialog however, as well as moving out of the static world and into the instance world
Unrelated criticism:
Less chatty text in your question, text that is completely unrelated to your actual problem at hand, and more text that tells us useful information that helps us to understand your problem and your code, and thereby helping us solve the problem.
I have this code:
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JFrame implements ActionListener {
private JPanel panel;
private JButton button;
private JTextField field,field2;
private JLabel labelx, labely;
public static void main(String[] args) {
Test Frame = new Test();
Frame.setSize(400, 400);
Frame.createGUI();
Frame.setVisible(true);
}
private void createGUI(){
setDefaultCloseOperation (EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new FlowLayout());
panel = new JPanel();
panel.setPreferredSize(new Dimension(300, 300));
panel.setBackground(Color.white);
window.add(panel);
button = new JButton();
button.setText("Teken water molecuul");
button.setBackground(Color.yellow);
button.addActionListener(this);
window.add(button);
labelx = new JLabel("x");
field = new JTextField(2);
labely = new JLabel("y");
field2 = new JTextField(2);
window.add(labelx);
window.add(field);
window.add(labely);
window.add(field2);
}
#Override
public void actionPerformed(ActionEvent e) {
Graphics paper = panel.getGraphics();
String x = field.getText();
String y = field2.getText();
//panel.setLocation(x,y); //this x and y don't work
paper.setColor(Color.blue);
paper.fillOval(50,50,50,50);
paper.fillOval(50,200,50,50);
paper.setColor(Color.black);
paper.drawLine(92,92,150,150);
paper.drawLine(92,207,150,150);
paper.setColor(Color.red);
paper.fillOval(100,100,100,100);
}
}
I want to set the location of the graphic to a specific X and Y coordinates I got using two textFields. If I change the x and y manualy to a number, the white screen moves. I don't want to move the white screen but only the graphic.
So, the input of the two textFields should determine the position of the graphic.
Result when I run the code now. The position isn't determined by the input of the text textFields now.
Custom painting is done by override the paintComponent(...) method of your panel, not by using the getGraphics() method.
So you need to create a custom class. This class would have two instance variables to control the x/y location. Then the painting code would reference these variables. You would also need to add a setter method to change the value of these variables.
The basic code would be something like:
public class CustomPainting extends JPanel
{
private int locationX;
private int locationY;
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.translate(locationX, locationY)
// add your painting code here
}
public setGraphicLocation(int locationX, int locationY)
{
this.locationX = locationX;
this.locationY = locationY;
repaint;
}
}
Then in the ActionListener code you need to invoke the setGraphicLocation( ) method of your custom class using the value found in the text fields.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.
I am trying to open a New Window by pressing the JButton. Now my actionPerformed method for the Jbutton is just closing the window after pressing it. I want it to open a new window as the old window closes. I know, this question is already had been asked, but I tried lot of things, no one seems to work perfectly.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.Random;
public class secondTab extends JFrame
{
static JTabbedPane Pane = new JTabbedPane();
static JPanel Second = new JPanel();
static JPanel second = new JPanel(); // This Panel is inside the Second Panel
static JButton guess1 = new JButton();
static String words[] = new String[9];
static Random getRandomWord = new Random();
static int rr;
static JButton Labels[] = new JButton[10];
public static void main(String args[])
{
//construct frame
new secondTab().show();
}
public secondTab()
{
// code to build the form
setTitle("Shopping Cart");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
// position tabbed pane
GridBagConstraints gridConstraints = new GridBagConstraints();
gridConstraints.gridx = 1;
gridConstraints.gridy = 1;
Pane.setForeground(Color.YELLOW);
Pane.setBackground(Color.MAGENTA);
getContentPane().add(Pane, gridConstraints);
getContentPane().setLayout(new GridBagLayout());
// Tabs Starts From Here
Second.setLayout(new GridBagLayout());
words[1] = "JAVA";
words[2] = "FLOAT";
words[3] = "VOID";
words[4] = "MAIN";
words[5] = "STATIC";
words[6] = "FINAL";
words[7] = "PRIVATE";
words[8] = "CHAR";
words[9] = "IF";
rr = getRandomWord.nextInt(10);
for(int i = 1; i <=words[rr].length(); i++)
{
Labels[i] = new JButton();
gridConstraints.gridx = 0;
gridConstraints.gridy = 0;
second.add(Labels[i]);
}
gridConstraints.gridx= 0;
gridConstraints.gridx= 0;
Second.add(second, gridConstraints);
guess1.setText("New Word");
gridConstraints.gridx = 0;
gridConstraints.gridy = 2;
Second.add(guess1, gridConstraints);
Here is my button's Action Performed method
// Action Performed method for the JButton guess1
guess1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
dispose();
}
});
Pane.addTab("Game ", Second);
pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds((int) (0.5 * (screenSize.width - getWidth())), (int) (0.5 *
(screenSize.height - getHeight())), getWidth(), getHeight());
}
}
Just add your new panel statement after the dispose(). for example : add
guess1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
new JFrame("New Window").show();
}
});
and one more point - you have created array of 9 element and you are trying to insert at 10 index that throws ArrayIndexOutOfBound exception.
You have to remove static keyword for your button and other controls, then you can do this
JTabbedPane Pane = new JTabbedPane();
JPanel Second = new JPanel();
JPanel second = new JPanel(); // This Panel is inside the Second Panel
JButton guess1 = new JButton();
String words[] = new String[10];
Random getRandomWord = new Random();
int rr;
JButton Labels[] = new JButton[10];
You have to create new instance of same class and show it
guess1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
new secondTab().show();
}
});
So, rather then closing the current window and creating a new instance of the window, which is just annoying (and a little lazy).
You should provide a means by which you can reset the state of your UI.
You should do this via some method call that resets the internal state and updates the UI.
You could accomplish the same thing by removing the "game" panel, creating a new instance of it and adding it back to the frame.
Blinking frames is a bad idea - IMHO
Hi,
Please try like this.. It may help..
guess1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
dispose();
new AnotherJFrame();
}
}
---------------------------------------------
import javax.swing.JFrame;
import javax.swing.JLabel;
public class AnotherJFrame extends JFrame
{
public AnotherJFrame()
{
super("Another GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new JLabel("Empty JFrame"));
pack();
setVisible(true);
}
}
I see your question has been answered, so this does not address your problem. I just thought I'd share some things you might want to condider fixing:
Don't use show()/hide(), because they are deprecated. [More info]
Use setVisible(true/false) respectively. [More info]
You don't have to add a new 'GridBagLayout()' before adding each component into the same container. I.e., you can remove the second getContentPane().setLayout(new GridBagLayout()); [More info]
Just make sure you understand that array-indices in Java (and all programming languages I know od - which isn't that much...but still) are zero-based ! [More info]
In order to find the center of the "usable" screen size Toolkit.getDefaultToolkit().getScreenSize(); isn't enough, since it includes screen-insets (e.g. non-visible margins, taskbars etc). You need to also use Toolkit.getDefaultToolkit().getScreenInsets(GraphicsConfiguration); and substract left and right insets from screen-width as well as top and bottom insets from screen-height.
If all you need is center a JFrame on the screen, you can simply use setLocationRelativeTo(null). [More info]
see the below link... It may help for you..
Java swing application, close one window and open another when button is clicked
I need to clean my labelResult each time on textField Action, but on the first time it adds 'null' in front of string and then - prints new string right after. Please help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Frame extends JFrame implements ActionListener {
boolean isDirect = true;
String[] typeStr = {"direct", "invert"};
JLabel labelTip = new JLabel("Choose 'direct' OR 'invert' to print your next line in direct order or inverted respectively.");
JTextField textField = new JTextField("Some text!", 40);
JComboBox comboBox = new JComboBox(typeStr);
EventProcessing eventProcessing = new EventProcessing();
JLabel labelResult = new JLabel();
public Frame() {
setLayout(new BorderLayout());
getContentPane().add(labelTip, BorderLayout.PAGE_START);
getContentPane().add(comboBox, BorderLayout.CENTER);
getContentPane().add(textField, BorderLayout.AFTER_LINE_ENDS);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textField.addActionListener(this);
pack();
}
public void actionPerformed(ActionEvent e) {
getContentPane().remove(labelResult);
labelResult = new JLabel();
labelResult.setText("");
if (!(comboBox.getSelectedItem()).equals("direct")) {
isDirect = false;
}
else {
isDirect = true;
}
labelResult.setText(eventProcessing.action(isDirect, textField.getText()));
getContentPane().add(labelResult, BorderLayout.PAGE_END);
pack();
}
}
#Tim I know that in official tutorial about JComboBox is used ActionListener, but for any of actions from JComboBox to the GUI is better look for ItemListener, there you are two states (always be called twice, but you can filtering between thes two options SELECTED / DESELECTED by wraping to the if ... else)
and your code should be only
Runnable doRun = new Runnable() {
#Override
public void run() {
labelResult.setText(eventProcessing.action(isDirect, textField.getText()));
add(labelResult, BorderLayout.PAGE_END);
//1) this.pack(); if you want to re-layout with effect to size of JFrame too
//2a revalidate();
//2b plus in most cases
//2b repaint(); relayout Container with fitting JComponents inside Container,
//2b but without resize of JFrame
}
};
SwingUtilities.invokeLater(doRun);
Without the code to EventProcessing.action() it's hard to determine, but I would guess you attempt to concatenate two strings, the first of which is null. Null strings get converted to the literal string "null."