Buttons all over the window - Java - java

I am trying to learn java and i am practicing with a simple program with 2 simple buttons. Here is my code :
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Askhsh 3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ColorJPanel application = new ColorJPanel();
frame.add(application);
frame.setSize(500,500);
frame.setVisible(true);
}
}
And the class ColorJPanel:
import java.awt.*;
import javax.swing.*;
public class ColorJPanel extends JPanel{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(Color.WHITE);
JButton arxikopoihsh = new JButton("Αρχικοποίκηση");
JButton klhrwsh = new JButton("Κλήρωση");
add(arxikopoihsh);
add(klhrwsh);
this.revalidate();
this.repaint();
}
}
As you can see the only thing i want to do for now is to place 2 simple buttons that do nothing! Here is my output:
http://imageshack.us/photo/my-images/847/efarmogh.jpg/
When i am running the application i am seeing the buttons filling the window!
Note that if i remove the "this.revalidate();" command i have to resize the window to see the buttons !
Thanks very much for your time :)

Don't add components in paintComponent. This method is for painting only, not for program logic or to build GUI's. Know that this method gets called many times, often by the JVM and most of the time this is out of your control, and also know that when you ask for it to be called via the repaint() method, this is only a suggestion and the paint manager may sometimes choose to ignore your request. The paintComponent method must be lean and fast as anything that slows it down will slow down the perceived responsiveness of your application.
In your current code, I don't even see a need to have a paintComponent method override, so unless you need it (if doing for instance custom painting of the component), I suggest that you get rid of this method (and the calls to repaint and revalidate). Instead, add your components in the class's constructor and make sure to pack your top level container after adding components and before calling setVisible(true). Most important -- read the Swing tutorials as this is all covered there.
e.g.,
Main.java
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Askhsh 3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ColorJPanel application = new ColorJPanel();
frame.add(application);
frame.pack();
frame.setVisible(true);
}
}
ColorJPanel.Java
import java.awt.*;
import javax.swing.*;
public class ColorJPanel extends JPanel{
public static final int CJP_WIDTH = 500;
public static final int CJP_HEIGHT = 500;
public ColorJPanel() {
this.setBackground(Color.WHITE);
JButton arxikopoihsh = new JButton("Αρχικοποίκηση");
JButton klhrwsh = new JButton("Κλήρωση");
add(arxikopoihsh);
add(klhrwsh);
}
// let the component size itself
public Dimension getPreferredSize() {
return new Dimension(CJP_WIDTH, CJP_HEIGHT);
}
}

Related

Is it possible to create a panel with a class on the left and right side?

I have been practicing my code with Java Swing and have gotten decent on controlling where to place some items, such as labels and or buttons, but I was wondering if you can do the same with classes? I have just a simple class with enough code to put a button in it and that's it, that I am trying to create an instance of the class and then control for to put on the left and right side but when I do, all it does is create two separate windows with the button in the middle and that's it. Am I doing something wrong, or can you not do classes the same way?
The code:
import java.awt.Color;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Fun extends JFrame
{
private final int WIDTH = 500;
private final int HEIGHT = 400;
public Fun()
{
setTitle("Fun Management");
setSize(WIDTH, HEIGHT);
BuildPanel west = new BuildPanel(); /// BuildPanel is the name of the class that has just a button in it.
BuildPanel east = new BuildPanel(); ///
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(west, BorderLayout.WEST); /// I am doing the same thing with the instances as I would with buttons or labesl
add(east, BorderLayout.EAST);
setVisible(true);
}
public static void main(String[] args)
{
new Fun();
}
}
I took your code and created the following GUI.
Oracle has a rad tutorial, Creating a GUI With Swing, that will show you how to create Swing GUIs. Skip the Netbeans section.
Always start your Swing application with a call to the SwingUtilities invokeLater method. This method ensures that your Swing components are created and executed on the Event Dispatch Thread.
Use Swing components. Don't extend a Swing component unless you want to override one or more of the component methods.
The JFrame methods must be called in a specific order. This is the order I recommend for most Swing applications. Use the JFrame pack method and let the components size the JFrame.
I created a BuildPanel class to build a JPanel. There are good reasons to do this, but be careful. You have to manage each instance of the class you create. As an example, what if you want the text of the two buttons to be different? What if you want to assign two different ActionListener classes, one to each button?
Here's the complete runnable code. I made the BuildPanel class an inner class so I can post the code as one block.
import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TwoPanelExample implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new TwoPanelExample());
}
#Override
public void run() {
JFrame frame = new JFrame("Fun Management");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BuildPanel west = new BuildPanel();
BuildPanel east = new BuildPanel();
frame.add(west.getPanel(), BorderLayout.WEST);
frame.add(east.getPanel(), BorderLayout.EAST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class BuildPanel {
private final JPanel panel;
public BuildPanel() {
this.panel = createMainPanel();
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(5, 30, 5, 30));
JButton button = new JButton("Click Me");
panel.add(button);
return panel;
}
public JPanel getPanel() {
return panel;
}
}
}

Error occurs when trying to start Java GUI in IntelliJ

GameLauncher class
package me.beanbeanjuice;
import me.beanbeanjuice.utilities.Game;
import me.beanbeanjuice.utilities.filehandlers.DictionaryHandler;
import me.beanbeanjuice.utilities.filehandlers.DistributionHandler;
public class GameLauncher {
public GameLauncher() {
new Window();
}
public static void main(String[] args) {
new DictionaryHandler();
new DistributionHandler();
new Game();
// TESTING. MenuScreen() should start first. MenuScreen() when "startButton" is hit, it should start game.
//new Window();
new GameLauncher();
}
}
Window class
package me.beanbeanjuice;
import javax.swing.JFrame;
public class Window extends JFrame {
public Window() {
super();
setTitle("Boggle");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(new GamePanel(720, 1280));
add(getContentPane());
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
GamePanel class
package me.beanbeanjuice;
import javax.swing.*;
import java.awt.*;
public class GamePanel extends JPanel {
public static int width;
public static int height;
public GamePanel(int width, int height) {
super();
setPreferredSize(new Dimension(width, height));
setFocusable(true); // Allows the JPanel to have input as soon as the JFrame is made.
requestFocus();
}
}
Error Message
Error Message in GameLauncher class
Hello, I'm following a tutorial for making a Java GUI in IntelliJ, and it won't even start. If you look at the last link, it shows this weird "error" and it won't start the GUI. It leads to the "Error Message" link as shown for link number 4. How do I fix this? I followed the tutorial exactly and even tried making a new project to no avail. I've tried swapping the Window() and GameLauncher() calls in the GameLauncher class but it is still not working. I've also tried with and without the super() call.
So the issue was with a display driver, however, I do not know if it still occurs. What fixed it was unplugging all of my external monitors, running the code, plugging them back in, stopping the code, running the code, then it worked again.
In Window Constructor in the Window class, at this line add(getContentPane()); you are adding container's parent to itself. This line is the same as writing getContentPane.add(getContentPane()).
I dont know what do you mean to put in the frame. Using JFrame you need to add the child to the JFrame's content pane. Removing this line works for me.
https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html

Add Textfields on Jframe at Runtime

I am trying to create text-fields on frame by getting input at run-time. Is it possible? Or I have to create another frame for that. I tried this code, but it's not working. Please Help me out, and tell me what's wrong with this code.
import java.awt.BorderLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Check extends JFrame implements ActionListener
{
JTextField txtqty;
JTextField[] tfArr;
JPanel p1,p2;
JButton bsmbt;
public Check()
{
GUIDesign();
}
public void GUIDesign()
{
p1 = new JPanel();
txtqty = new JTextField(10);
JButton bsmbt= new JButton("OK");
p1.add(txtqty);
p1.add(bsmbt);
p2=new JPanel();
p2.setLayout(null);
add(p1,BorderLayout.NORTH);
setSize(500, 500);
setVisible(true);
setLocation(100, 100);
bsmbt.addActionListener(this);
}
public static void main(String[] args)
{
new Check();
}
public void TFArray(JTextField[] temp)
{
int x,y,width,height;
x=10;y=30;width=50;height=20;
int no_of_textboxes = Integer.parseInt(txtqty.getText());
temp=new JTextField[no_of_textboxes];
for(int i=0;i<no_of_textboxes;i++)
{
temp[i]= new JTextField(10);
temp[i].setBounds(x, y, width, height);
x+=(width+10);
p2.add(temp[i]);
}
add(p2);
}
#Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(this, txtqty.getText());
TFArray(tfArr);
}
}
->Method TFArray() isn't working.
You have many errors in your code:
public void TFArray(JTextField[] temp): method names should start with lowerCamelCase
You're extending JFrame, you shouldn't extend JFrame, because when you extend it your class is a JFrame, JFrame is rigid so you can't place it inside anything else, instead you might consider creating a JFrame instance and if you ever need to extend JComponent extend from JPanel.
JButton bsmbt= new JButton("OK"); the variable bsmbt is a local variable inside your constructor, your global variable bsmbt is not used anywhere, and if you try to use it later you'll get a NullPointerException, instead change that line to:
bsmbt= new JButton("OK");
You're using null layout for p2, instead use a proper Layout manager and read Null layout is evil and Why is it frowned upon to use a null layout in swing?. Swing was designed to work with different PLAFs, screen sizes and resolutions, while pixel perfect GUIs (with setBounds()) might seem like the best and faster way to create a complex GUI in Swing, the more GUIs you make, the more errors you'll get due to this.
To solve your problem call revalidate() and repaint()
The above code creates 2 textfields. but when I again put some value and submit it, it doesn't seem to reflect any changes.
That might be because you're overriding x, y, height and width variables each time you enter TFArray method. But that is a guess, if you want a real answer, follow the suggestions above and post a proper and valid Minimal, Complete, and Verifiable example

paintComponent does painting on its own

My problem is, when I press a button paintComponent should be called then a figure should be drawn on the JPanel, Unfortunately paintComponent draws the figure when the program is loaded, in that case the button is useless.
I made a small version of my program, to make it easy and fast to read and detect the problem.
This code here is not the original one but it demonstrates the same problem.
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class TestPaint extends JPanel implements ActionListener {
private JButton button_1 = new JButton( "Draw Oval" );
public TestPaint() {
add(button_1);
}
#Override
public void actionPerformed(ActionEvent e) {
if ( e.getSource() == button_1 )
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(10, 10, 100, 100);
}
}
To run the program
import javax.swing.JFrame;
public class RunPaint {
public static void main(String[] args) {
TestPaint paint_g = new TestPaint();
JFrame frame = new JFrame("Testing");
frame.add(paint_g);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
As a simple solution you can create an instance variable for your class:
private Boolean buttonPressed = false;
Then in your actionListener you set the value to true.
and in your paintComponent() method you add code like:
if (buttonPressed)
g.drawOval(...);
A better (and more complicated solution) is to keep a List of objects to paint. Initially the List will be empty, and when you press the button you add an object to the List. Then the painting code just iterates through the List to paint the objects.
Check out Custom Painting Approaches for more ideas. The example code doesn't do exactly this, but it does show how to paint from a List.
Let your actionPerformed() implementation add the desired geometric figure to a List<Shape> and have paintComponent() iterate through the list to render the shapes. A complete example is seen here.

Static to non static method

I am trying to move from a static main() to a non static method called paintComponent(), but the problem I am having is I can not move from Static to Non static in the way which I have. The class is a follows, where hunter and hunted are external classes:
import javax.swing.JFrame;
import java.awt.Graphics;
public class Main extends JFrame{ //Public class: Available for all other classes to refer to
private static final long serialVersionUID = -4511248732627763442L;
public static void main(String[] args){
frame();
repaint();
move(); //Passes to the method move() in the class Main()
}
public static JFrame frame(){
JFrame frame = new JFrame("Hunter VS Hunted"); //Sets the window title
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); //Sets the size of the window
frame.setVisible(true); //Says to display the window
frame.setResizable(false); //Sets it so the screen cannot be adjusted
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Closes the window when the x is pushed
System.out.println("Frame works.");
return frame;
}
public void paintComponent(Graphics g){
super.paintComponents(g); //Assigns a graphics value to g, so that it can be passed to other methods
Hunted.paint(g);
Hunter.paint(g);
System.out.println("Main.paintComponent works.");
}
public static void move(){
Hunter.move(); //Passes to move() in the Hunter class
Hunted.move(); //Passes to move() in the Hunter class
}
}
Bear in mind I am a beginner, so please try to keep it simple!
You need to call repaint and paintComponents using an object.
JFrame frame = frame();
frame.repaint();
move();
Every non-static method needs to be called from an object. Static methods belongs to the class, so you can call them without an object.
repaint and paintComponents belongs to the JFrame object. They are not static and so they need to be called using an object (repaint will call paintComponents).
Your 'frame()' method will return a JFrame object. So you can call the repaint() method using the JFrame object that is returned from the 'frame()' method.
Having said that, I'm not sure what you are trying to accomplish in your code, and even if my explanation will resolve a Compilation-Error, without further elaboration, it might not accomplish what you are trying to achieve.
you have got some messed up code! but let me clean it up a bit, make it more presentable. However it is up to you to get it to work now. I have created another class for your jframe and adjusted your extra / repetitive code in the constractor.
btw i know nothing about haunted and haunter.
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main {
public static void main(String[] args){
myFrame x = new myFrame("Hunter VS Hunted");
x.ui(x.getContentPane());
}
}
class myFrame extends JFrame {
public myFrame(String name){
// constractor
super(name); //Sets the window title
setExtendedState(JFrame.MAXIMIZED_BOTH); //Sets the size of the window
setVisible(true); //Says to display the window
setResizable(false); //Sets it so the screen cannot be adjusted
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Closes the window when the x is pushed
}
public void ui(final Container pane){
JLabel test = new JLabel("test frame");
pane.add(test);
System.out.println("Frame works.");
}
}
now if you include graphics in this class, everytime you call up repaint(), it will call the function paintComponent(Graphics g). good luck :)

Categories