JFrame text components not showing up properly - java

I was playing around with JFrame today and had trouble getting a JButton component to display text properly. The text displayed in JButton is cut off at the end. I tried resizing the JButton component in order to make sure that the text could fit, but the same problem occurred. The problem looks like this:
Here is the code:
import javax.swing.JFrame;
public class Launcher {
public static void main(String[] args) {
JFrame jFrame = new JFrame("Frame");
jFrame.setSize(400, 400);
jFrame.setDefaultCloseOperation(jFrame.EXIT_ON_CLOSE);
jFrame.setLocation(400, 400);
jFrame.add(new Drawable(jFrame));
jFrame.setVisible(true);
}
}
Here is the other class in another .java file.
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Drawable extends JPanel {
private JButton button;
private JFrame jFrame;
public Drawable(JFrame jFrame) {
this.jFrame = jFrame;
button = new JButton("This text does not show properly");
button.setPreferredSize(new Dimension(200, 25));
button.setLocation(jFrame.getWidth() / 2 - 50, jFrame.getHeight() / 2 - 12);
this.add(button);
}
}
I understand that this might be a problem with my project's setup, so if anyone needs me to post it I can do so.

Remove the statement
button.setPreferredSize(new Dimension(200, 25));
which is being used by the panel's layout manager to constrain the button width

Related

JLabel showing ellipses when is has space to show full label

JLabel showing ellipses when is has space to show full label
my code:
​import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.basic.BasicLookAndFeel;
import com.bulenkov.darcula.DarculaLaf;
public class GUI implements ActionListener {
private int count = 0;
private JLabel label;
private JFrame frame;
private JPanel panel;
public GUI() throws UnsupportedLookAndFeelException {
BasicLookAndFeel darcula = new DarculaLaf();
UIManager.setLookAndFeel(darcula);
frame = new JFrame();
JButton button = new JButton("Click Me");
button.addActionListener(this);
label = new JLabel("Number of clicks: 0");
panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(20, 100, -85, 100));
panel.setLayout(new GridLayout(5, 1));
panel.add(button);
panel.add(label);
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
///frame.setTitle("Cool GUI");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws UnsupportedLookAndFeelException {
new GUI();
}
#Override
public void actionPerformed(ActionEvent e) {
count++;
label.setText("Number of clicks: " + count);
}
}
Oracle has a good tutorial that teaches the basics of Swing, Creating a GUI With JFC/Swing. Skip the Netbeans section.
I created the following GUI.
Here's what I did.
I started my Swing GUI with a call to the SwingUtilities invokeLater method. This method ensures that all of the Swing components are created and executed on the Event Dispatch Thread.
I separated the code to construct the JFrame from the code to construct the JPanel. The JFrame methods have to be called in a certain order. This is the order I use for most of my Swing applications.
I construct the JPanel in Swing component order. I keep all methods having to do with a particular Swing component together.
I put the "Number of clicks:" text in one place.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BasicGUI implements ActionListener, Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new BasicGUI());
}
private int count;
private JLabel label;
public BasicGUI() {
this.count = 0;
}
#Override
public void run() {
JFrame frame = new JFrame("Cool GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JButton button = new JButton("Click Me");
button.addActionListener(this);
panel.add(button);
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
updateLabel(0);
panel.add(label);
return panel;
}
public void updateLabel(int count) {
label.setText("Number of clicks: " + count);
}
#Override
public void actionPerformed(ActionEvent event) {
updateLabel(++count);
}
}
BasicLookAndFeel darcula = new DarculaLaf();
UIManager.setLookAndFeel(darcula);
Don't use a 3rd party LAF when asking a basic question.
We don't know if the problem is related to the LAF or the standard classes of the JDK.
JLabel showing ellipses when is has space to show full label
Well actually it doesn't have space because you use the pack() method and all components are displayed at their preferred size based on the preferred size of the components and of the Borders applied to the components.
When I run your code (using the default LAF) the text displays correctly at startup.
This is because the width of the panel is controlled by the preferred width of the JButton since it is the larger component.
However, if I change the text of the button to be:
label.setText("Number of clicks made: " + count);
now the width of the panel is controlled by the preferred width of the label since it is greater than that of the button.
Again, at startup the text displays properly
However, if you click the button 10 times then the "count" changes from a one digit number to a two digit number which increases the preferred size of the label causing the "..." to appear.
A simple solution is to use:
count++;
label.setText("Number of clicks made: " + count);
frame.pack();
Now the frame will be resized to accommodate the newly calculated preferred size of the label.
panel.setLayout(new GridLayout(5, 1));
Also, don't hardcode the "rows" of the GridLayout. The above code reserves space for 5 components even though you only have 2.
Instead use:
panel.setLayout(new GridLayout(0, 1));
which indicates a single column with any number of components.
Then you can use the EmptyBorder properly to give it symmetry on all sides:
//panel.setBorder(BorderFactory.createEmptyBorder(20, 100, -85, 100));
panel.setBorder(BorderFactory.createEmptyBorder(20, 100, 20, 100));
I think GridBagLayout asks your JLabel about the required size when the UI is initialized. Then the JLabel is assigned the requested size.
During runtime the String that needs to be displayed by the JLabel changes, and actually it gets longer. But no re-layout is happening, therefore the JLabel is not allowed to use more space - even if on the screen it seems there is plenty of space.
The solution is to either tell GridBagLayout to reserve plenty of space for that component, or allow for dynamic scaling. Check the GridBagLayout tutorial for details.

When I click my JButton, the JLabel doesn't show on the window,

I tried to make a JButton that would put a JLabel in the window, but when I click the button, it doesn't seem to put the JLabel in the window. The button seems to work when I use it for the console, but not for putting the JLabel in the window. Why is this, and what should I do?
Here's my code:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AnimaleseTranslator implements ActionListener {
private static JPanel panel;
private static JLabel label;
public AnimaleseTranslator() {
JFrame frame = new JFrame();
panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(220, 391, 220, 391));
panel.setLayout(new GridLayout(0, 1));
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null); // centers the JFrame
frame.setTitle("Animalese Translator");
frame.setVisible(true);
JButton button = new JButton("Click me!");
button.setBounds(100, 100, 98, 55);
button.addActionListener(this);
panel.add(button);
label = new JLabel("lkdsajflksdjlaskdjf");
label.setBounds(200, 200, 50, 50);
}
public static void main(String[] args) {
new AnimaleseTranslator();
}
#Override
public void actionPerformed(ActionEvent e) {
panel.add(label);
}
}
but when I click the button, it doesn't seem to put the JLabel in the window.
The setBounds(...) statement does nothing. Swing uses layout managers by default and the layout manager will set the size/location of each component. So get rid of the setBounds() statement because it is confusing.
Components need to be added to the frame BEFORE the frame is made visible. The pack() or setVisible() statement will then invoke the layout manager.
After you add a component to panel on a visible frame you need to invoke panel.revalidate() to invoke the layout manager. So you need to add the revalidate() in the ActionListener.
Get rid of the setBorder(...) statement until you better understand what it does. The problem with your current code is the border is too big, so there is no room for the button and label to display properly.

JPanel transition, what is wrong with my code?

I am new to java, and learning new things everyday.
Today i stumbled upon an error i just can not get fixed.
So i've got a JFrame with a JPanel inside, now I want to remove the Jpanel when i click on my Start game JLabel, and make it transition into my game JPanel ( for now i use a test JPanel)
JFrame class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MainMenu extends JFrame {
JPanel panel;
JFrame frame;
JButton playlabel;
public void mainmenu() {
frame = new JFrame();
panel = new JPanel();
playlabel = new JButton ("Nieuw Spel");
//frame
frame.setSize(new Dimension(800, 600));
frame.getContentPane().setBackground(new Color(14,36,69));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(frame.getMinimumSize());
frame.setVisible(true);
//panel
Dimension expectedDimension = new Dimension(690, 540);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setPreferredSize(expectedDimension);
panel.setMaximumSize(expectedDimension);
panel.setMinimumSize(expectedDimension);
panel.setBackground(new Color(14, 36, 69));
panel.add(playlabel);
playlabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
//playlabel
playlabel.setFont(new Font("Old English Text MT", Font.BOLD, 40));
playlabel.setBounds(250, 350, 50, 20);
playlabel.setForeground(new Color(217,144,39));
playlabel.setBackground(new Color(14,36,69));
playlabel.setBorderPainted(false);
playlabel.setFocusPainted(false);
playlabel.addActionListener(new PlayListener());
}
private class PlayListener extends JFrame implements ActionListener {
public void actionPerformed(ActionEvent e) {
JPanel panelgame = Game.Game();
this.remove(panel);
this.add(panelgame);
this.revalidate();
}
}
}
Game class:
package labyrinthproject.View;
import java.awt.Color;
import javax.swing.JPanel;
public class Game {
public static JPanel Game(){
JPanel panel = new JPanel();
panel.setSize(690, 540);
panel.setBackground(new Color(255,36,69));
return panel;
}
}
if anyone could explain this to me why this doesn't work, it would be greatly appreciated!
Thank you very much!
Sincerely,
A beginner java student.
There are quite some issues in your code
Create the GUI on the event dispatch thread
Don't extend JFrame (you have three (three!) JFrames floating around there!)
Follow the naming conventions
Don't overuse static methods
Only store the instance variables that you really need to represent your class state
Don't use manual setSize or setBounds calls. Use a LayoutManager instead
The call to frame.setVisible(true) should be the last call, after the frame has been completely assembled
Consider a CardLayout for switching between panels ( http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html )
Slightly cleaned up, but the exact structure depends on what you actually want to achieve at the end:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MainMenu extends JPanel
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame mainFrame = new JFrame();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainMenu = new MainMenu();
mainFrame.getContentPane().add(mainMenu);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
MainMenu()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
Dimension expectedDimension = new Dimension(690, 540);
setPreferredSize(expectedDimension);
setBackground(new Color(14, 36, 69));
JButton newGameButton = new JButton ("Nieuw Spel");
newGameButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
newGameButton.setFont(new Font("Old English Text MT", Font.BOLD, 40));
newGameButton.setForeground(new Color(217,144,39));
newGameButton.setBackground(new Color(14,36,69));
newGameButton.setBorderPainted(false);
newGameButton.setFocusPainted(false);
newGameButton.addActionListener(new PlayListener());
add(newGameButton);
}
private class PlayListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
removeAll();
GamePanel gamePanel = new GamePanel();
add(gamePanel);
revalidate();
}
}
}
class GamePanel extends JPanel
{
GamePanel()
{
setBackground(new Color(255,36,69));
}
}
You should use a JButton and not a JLabel. Then:
you add to your JButton : Your_JB.addActionListener(this); (don't forget to implement ActionListener to your class).
Now, we are gonna add the detector:
#Override
public void actionPerformed(ActionEvent e){
Object src = e.getSource();
if(src == Your_JB){
panel.setVisible(false);
}
}
When you click the button, it will make your panel disapear.
Try this:
this.remove(panel);
this.validate();
this.repaint(); //if you use paintComponent
this.add(panelgame);
this.revalidate();
Swing is hard to making nice UI. You just need to use validate() after remove().
I hope it's helpfull.

Blank JPanel after adding a JTextField

Working on adding a GUI to my simple craps simulation program.
Made a new JPanel and added a few JTextFields to it with a default text value. I get no error, and the code runs, but all I get is a blank window with nothing in it.
Here is the code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CrapsGUI extends JFrame
{
JPanel jp = new JPanel();
JLabel jl = new JLabel();
JTextField die1 = new JTextField("Die 1",30);
JTextField die2 = new JTextField("Die 2",30);
JTextField sum = new JTextField("Sum",30);
JTextField point = new JTextField("Point",30);
JTextField status = new JTextField("Status",30);
public CrapsGUI()
{
setTitle("Craps Simulator 2013");
setVisible(true);
setSize(400, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
jp.add(die1);
jp.add(die2);
jp.add(sum);
jp.add(point);
jp.add(status);
}
public static void main(String[] args)
{
Craps craps = new Craps();
CrapsGUI crapsGUI = new CrapsGUI();
}
}
Thanks in advance!
You haven't added the JPanel that contains the visible components.
add(jp);
Three things come to mind
Make sure you are starting your UI's from within the context of the Event Dispatching Thread. See Initial Threads for more details
Call setVisible only after you have finished creating your UI
It would also be helpful if you added something to you frame. Try using add(jp)
try this one:
public static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("Sample Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// first text box
JPanel textbox1Panel = new JPanel();
textbox1Panel.setLayout(new BoxLayout(textbox1Panel, 0));
textbox1Panel.setOpaque(true);
textbox1Panel.setBackground(new Color(100, 0, 131));
textbox1Panel.setPreferredSize(new Dimension(300, 300));
textbox1Panel.add(die1);
textbox1Panel.add(die2);
textbox1Panel.add(sum);
textbox1Panel.add(point);
// Set the menu bar and add the label to the content pane.
frame.getContentPane().add(textbox1Panel, BorderLayout.SOUTH);
// Display the window.
frame.pack();
frame.setVisible(true);
}

How can we add JScrollPane on JTextArea in java?

Can anybody tell me what is the problem in following program? I want to fit JScrollPane on JtextArea but when I add it then JTextArea is not visible.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Area extends JFrame
{
private JTextArea ta;
private JTextField tf;
JScrollPane jp;
public Area()
{
super("Text Area");
tf=new JTextField();
tf.setBounds(100,350,300,30);
add(tf);
ta=new JTextArea();
ta.setBounds(100,100,300,200);
jp= new JScrollPane(ta);
add(jp);
setLayout(null);
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String...s)
{
new Area();
}
}
I see several problems:
Don't use a null layout; do use a real layout.
The default layout of JFrame is BorderLayout; the default position is CENTER; only one component can occupy a position at a time; the example below uses NORTH & CENTER.
Use the appropriate constructor parameters to size the text components initially.
The scrollbar will appear automatically whenever the scrollpane is smaller than the enclosed component; resize the frame to see the effect.
As shown here, the frame's size is made smaller for effect.
See also Initial Threads.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/** #see https://stackoverflow.com/a/19215436/230513 */
public class Area extends JFrame {
public Area() {
super("Text Area");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField tf = new JTextField(12);
add(tf, BorderLayout.NORTH);
JTextArea ta = new JTextArea(24, 12);
JScrollPane jp = new JScrollPane(ta);
add(jp, BorderLayout.CENTER);
pack();
// arbitrary size to make vertical scrollbar appear
setSize(240, 240);
setLocationByPlatform(true);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Area();
}
});
}
}
Try this:
public Area()
{
super("Text Area");
tf=new JTextField();
tf.setBounds(100,350,300,30);
add(tf);
ta=new JTextArea();
jp= new JScrollPane(ta);
jp.setBounds(5, 5, 100, 100);
add(jp);
setLayout(null);
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
You have to use setBounds on JScrollPane, not on JTextArea
sounds like its added but its not shown because of the policy try this:
jp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

Categories