JTabbedPane shows itself randomly - java

the problem I encountered is weird for me, because I was doing everything step by step, correctly (in my opinion) and finally when I could say I finished one part of my program it appeared to make a fun of me. The actual problem is that in GUI I created I used a JPanel, then I've put it into a JTabbedPane which I've finally put into a JFrame. Everything is fine and works apart from times when it doesn't. I know it sounds strange, but after running program once I get what I wanted (Frame with tabbed pane containing panel with some stuff in it) and then when I run it again it either show the correct thing again or just empty frame. The worst thing is that it's so random, I haven't got a clue what can be wrong, I don't even know what exactly should I google to find it out. The code is:
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.*;
public class GUI extends JFrame {
JFrame frame = new JFrame("WakeOnLan script generator");
JPanel panel1 = new JPanel(null);
JTextArea text; //= new JTextArea("test");
JScrollPane scroll = new JScrollPane();
JButton but = new JButton("test");
JTabbedPane tab = new JTabbedPane();
public GUI() {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = frame.getSize().width;
int h = frame.getSize().height;
int x = (dim.width-w)/3;
int y = (dim.height-h)/4;
frame.setSize(500,500);
frame.setLocation(x,y);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(null);
createTab1();
tab.addTab("Tab 1", panel1);
tab.setVisible(true);
tab.setBounds(0, 0, 500, 500);
frame.add(tab);
}
public void createTab1(){
text = new JTextArea("test");
text.setVisible(true);
scroll.setViewportView(text);
scroll.setBounds(10,10,465,300);
panel1.setLayout(null);
panel1.add(scroll);
panel1.setVisible(true);
panel1.setSize(500,500);
//panel.setBackground(Color.blue);
}
}
And then I just run it in the main method in other class:
public class GUIStarter {
public static void main(String[] args) {
GUI start = new GUI();
}
}
So could anyone give me an answer or just a hint?
Thank you.

You should call frame.setVisible(true) after adding all your components to your JFrame. So try moving it to the end of your constructor.
Alternatively, you can call frame.validate() after all the components have been added.

Related

How do I add a scrollbar to a JFrame with setLayout(null)?

I have some components which I need to use setBounds() on, hence the reason why I'm using the setLayout(null).
But some of my components are out the window(below the Y-axis). I was wondering if there is a way to add a scrollbar to navigate down the window so as to see all the remaining components. A screenshot of my window is below.
Output of my window image:
That GUI would be simple to produce using layouts. Put the component displaying the list (which looks well suited to being a JTable, given the two pieces of data per row / line) into a JScrollPane. Put the scroll pane into the CENTER of a BorderLayout. Put the red label into the PAGE_START of the border layout. Then .. oh wait, the job is done!
This is what it might look like (using a JTextArea instead of a table).
can u please post a copy of this code.
Try implementing it based on the instructions above. If there is a problem, post a minimal reproducible example of your attempt.
Since you are refering to the items in the scrolling area as components, and not as texts in a JTextArea, please have a look at the below.
import java.awt.*;
import javax.swing.*;
import java.util.Random;
public class Mainframe {
private JFrame f;
Box box;
JScrollPane scrollPane;
Random rand = new Random();
public static void main(String[] args) {
new Mainframe().go();
}
private void go() {
box = new Box(BoxLayout.Y_AXIS);
JLabel label = new JLabel("Possible Paths and Total Distances");
label.setForeground(Color.RED);
for (int i = 0; i < 200; i++) {
box.add(Box.createRigidArea(new Dimension(0, 2)));// creates space between the components
box.add(new JLabel(i + " : " + rand.nextInt(10000)));
}
scrollPane = new JScrollPane(box);
Dimension dim = new Dimension(box.getComponent(0).getPreferredSize());
scrollPane.getVerticalScrollBar().setUnitIncrement(dim.height * 2); // adjusts scrolling speed
//scrollPane.getViewport().setBackground(Color.WHITE);
f = new JFrame();
f.getContentPane().add(label, BorderLayout.NORTH);
f.getContentPane().add(scrollPane, BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(640, 480);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

Why does my JFrame randomly shrink when starting on Mac?

When working on my mac laptop I have recently noticed that my frame sometimes shrinks when the program starts. It is about 70-90% that it does shrink.
It works as expected on a PC but not on any mac I have tried it on. I have tried to narrow it down a bit (to the code below) but from here I can't find any reason for it not working. Some friends of mine think it might have something to do with mac's own window manager. I don't know.
I am fairly new to this, just FYI.
public class Worms extends JFrame{
public static void main(String[] args) {
new Worms();
}
private JButton startGame;
public Worms(){
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Container contentPane = this.getContentPane();
//if i change it so it uses a new dimension not "screenSize" it works
contentPane.setPreferredSize(screenSize);
JPanel menu = new JPanel();
startGame = new JButton("Start Game");
menu.add(startGame);//or if i remove this button it also works
this.add(menu);
this.pack();
this.setVisible(true);
}
}
It starts in "fullscreen" than it shrinks down to the left corner. If I drag it back to normal size it works as normal.
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Container contentPane = this.getContentPane();
//if i change it so it uses a new dimension not "screenSize" it works
contentPane.setPreferredSize(screenSize);
The content pane should not have the preferred size set to the screen size. That is too large, and does not account for the frame decorations or 'chrome'.
Here is a different approach that should work reliably across systems. It sets the extended sate of the frame.
import java.awt.*;
import javax.swing.*;
public class Worms extends JFrame{
public static void main(String[] args) {
new Worms();
}
private JButton startGame;
public Worms(){
JPanel menu = new JPanel();
startGame = new JButton("Start Game");
menu.add(startGame);
this.add(menu);
this.pack();
// this should do what you seen to want
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
// this is just polite..
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setVisible(true);
}
}
Note that Swing / AWT GUIs should be created & updated on the Event Dispatch Thread. The example above does not add that, for the sake of simplicity.

Java Swing blank screen instead of window displayed

I'm following through a book called "The JFC Swing Tutorial (Second Edition)" and I'm pretty much at the start I have followed this code and it should be displaying the button and the label in the content pane, but All im getting is a blank screen. any ideas?
Thanks.
import java.awt.GridLayout;
import javax.swing.*;
public class m extends JFrame
{
void UserFrame()
{
//JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Hellow You");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jp = new JPanel(new GridLayout(0,1));
//makes label
JLabel label = new JLabel("Sup ");
//adds to the frames content pane a label
frame.getContentPane().add(label);
JButton button = new JButton("Hai");
frame.getContentPane().add(button);
jp.add(button);
jp.add(label);
jp.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
//pack set the window to what it needs AKA to display all components
frame.pack();
//frame.setSize(250, 250);
//shows window
frame.setVisible(true);
}
public static void main(String[] args)
{
final m window = new m();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
window.UserFrame();
}
});
}
}
Simply add
frame.add(jp);
just before
frame.pack();
What's happening here? You correctly add all your widgets to a JPane, but you basically threw that JPane away and didn't use it anywhere.
This will be sufficient just to get it to work properly.
If you want to do it correctly, you should also remove frame.getContentPane().add(label); and frame.getContentPane().add(button); (Thank you #dic19 for noting that!). These will not work the way you used it.

Creating a WordWrap method for a JTextarea - Java

I think im heading in the wrong direction. Im creating a notepad app. I have every method running perfectly except one - WordWrap
Its just a JTextarea inside a panel inside a frame.
I think i should be using a JScrollPane instead of a Textarea? Or aswell as it even?
How would i go about resizing the width of a textarea or am i correct in saying i need to insert a JScrollPane.
Edit
Ok so my attempt is gone wrong somehow. Text area doesnt work. Something possibly needs resizing.
public class TextEditor extends JFrame implements ActionListener{
JFrame textFrame = new JFrame();
JPanel textPanel = new JPanel();
JTextField textArea = new JTextField();
JScrollPane scroll = new JScrollPane(textArea);
JTextArea text = new JTextArea(24,33);
public TextEditor(String str){
super(str);
textFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
textFrame.add(textPanel);
textPanel=(JPanel)getContentPane();
textPanel.setLayout(new FlowLayout());
textPanel.setBackground(Color.WHITE);
// Create text Area
textPanel.add(scroll);
scroll.add(text);
textPanel.setFont(textAreaFont);
textArea.setFont(textAreaFont);
text.setFont(textAreaFont);
}
public static void main(String args[])
{
TextEditor notePad = new TextEditor("Notepad");
notePad.setSize(500,500);
notePad.setVisible(true);
notePad.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
Have a look at what I have tried to put together:
public class SO{
public static void main(String[] args) {
JFrame f = new JFrame();
JPanel p = new JPanel();
JTextArea outputArea = new JTextArea();
outputArea.setColumns(20);
outputArea.setRows(20);
outputArea.setLineWrap(true); //Set line wrap
outputArea.setWrapStyleWord(true); //set word wrap
JScrollPane sp = new JScrollPane(outputArea); //Create new scroll pane with textarea inside
p.add(sp); //add scrollPane to panel
f.add(p); //Add panel to frame
f.pack()
f.setLocationRelativeTo(null); //frame location
f.setVisible(true);
}
}
The scroll pane is created using the textarea in the constructor, this seems to allow the scroll pane to 'contain' the JTextArea, adding scroll bars when the text the area contains exceeds the limits. Earlier when creating the JTextArea I set two lines of code to set a word wrap on it, this stops words seeping off the sides by pushing them onto the next line. Have a look and see if it can help with your project.
Good Luck!
import java.awt.*;
import javax.swing.*;
public class TextEditor extends JFrame {
JFrame textFrame = new JFrame();
JPanel textPanel = new JPanel();
JTextArea textArea = new JTextArea(10,25);
public TextEditor(String str){
super(str);
textFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE); // nicer
add(textPanel);
textPanel.setLayout(new GridLayout());
textPanel.setBackground(Color.WHITE);
// Create text Area
JScrollPane scroll = new JScrollPane(textArea);
textPanel.add(scroll);
}
public static void main(String args[])
{
TextEditor notePad = new TextEditor("Notepad");
notePad.setVisible(true);
notePad.setDefaultCloseOperation(EXIT_ON_CLOSE);
notePad.pack();
}
}
There were so many things wrong in that short code that I lost track of the changes. Two things I can recall are:
The code was quite confused about what was a JTextField and what was a JTextArea.
It added strange things to other strange things for no apparent reason.

Does Container.getComponents() return references to the original components?

I'm using Container.getComponents() to get an array of Components stored inside the Container. I'm then modifying one of these Components (which happens to be a JLabel), but the changes are not showing on the GUI.
So I'm thinking maybe the method creates new instances of each Component which prevents me from making changes to the original component?
Here's my code:
Component[] components = source.getComponents();
if(components.length >= 2) {
if(components[1] instanceof JLabel) {
JLabel htmlArea = (JLabel) components[1];
htmlArea.setText("<html>new changes here</html>");
htmlArea.revalidate();
}
}
It is either another problem outside of the code, or you are doing this from the wrong thread.
Any changes on Swing components should be done in the event dispatch thread. Often is it most easy to surround the changing code with EventQueue.invokeLater(...) (or SwingUtilities.invokeLater, this is the same).
And make sure your component is actually visible on the screen.
There is no need to revalidate() or repaint() anything (unless you are doing something really strange)!
Where is your SSCCE that demonstrates your problem???
It works fine for me:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class TabbedPaneLabel extends JFrame
{
JTabbedPane tabbedPane;
public TabbedPaneLabel()
{
tabbedPane = new JTabbedPane();
add(tabbedPane);
tabbedPane.addTab("First", createPanel("<html>label with text</html>"));
tabbedPane.addTab("Second", createPanel("another label"));
JButton remove = new JButton("Change Label on first tab");
add(remove, BorderLayout.SOUTH);
remove.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Component[] components = tabbedPane.getComponents();
JPanel panel = (JPanel)components[0];
JLabel label = (JLabel)panel.getComponent(0);
String date = new Date().toString();
label.setText("<html>" + date + "</html>");
}
});
}
private JPanel createPanel(String text)
{
JPanel panel = new JPanel();
panel.add( new JLabel(text) );
return panel;
}
public static void main(String args[])
{
TabbedPaneLabel frame = new TabbedPaneLabel();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

Categories