IntelliJ GUI Form not appearing - java

I'm making a simple weather app using IntelliJ and built in form designer. I have made and designed a form and edited the bound class file accordingly. When I actually run the code, the form I designed does now show up at all, in fact just the last line (maxtemp) is the only value that shows up on an empty white screen.
P.S I am using Gradle to build, I have also set the GUI designer to use Java source code instead of byte code (since Gradle does not support the byte code)
import org.json.JSONException;
import org.json.JSONObject;
import javax.swing.*;
import java.awt.*;
public class Frame extends JFrame {
// Get the API
private API api = new API();
// Form elements
public JPanel mainPanel;
public JLabel text;
public JLabel category;
public JLabel mintemp;
public JLabel maxtemp;
public JLabel link;
public Frame() throws Exception, JSONException {
initFrame();
}
public void initFrame() throws Exception, JSONException {
// Get API response
JSONObject wjson = api.connection();
// Filter response and get data
String[] data = api.respFilter(wjson);
// Swing components
mainPanel = new JPanel(new BorderLayout());
text = new JLabel();
category = new JLabel();
mintemp = new JLabel();
maxtemp = new JLabel();
link = new JLabel();
// Add to the frame
add(mainPanel);
add(text);
add(category);
add(mintemp);
add(maxtemp);
text.setText(data[0]);
category.setText(data[1]);
mintemp.setText(data[3]);
maxtemp.setText(data[4]);
}
public static void main(String[] args) throws Exception, JSONException {
JFrame app = new Frame();
app.setTitle("Java-WeatherApp");;
app.setSize(900, 600);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setLocationRelativeTo(null);
app.setVisible(true);
}
}
I'm pretty new to Java and very new to the form builder on IntelliJ. Unfortunately I could not find any good tutorials on the form builder. Any help is appreciated!

A JFrame has BorderLayout as a default layout.
In your initFrame() method when you call,
add(mainPanel);
add(text);
add(category);
add(mintemp);
add(maxtemp);
You are adding all the swing components to the JFrame. Since, you are not specifying the position of a component and since the JFrame has BorderLayout, only one component is added to the JFrame that is the last component you add to it, which the maxtemp Jlabel.
You should specify the position of a component when adding to the JFrame having BorderLayout as following,
add(minTemp, BorderLayout.NORTH);
I suggest you to learn more about BorderLayout and LayoutManagers.
OR,
You can use code similar to this,
// Swing components
mainPanel = new JPanel(new GridLayout(4, 1));
text = new JLabel();
category = new JLabel();
mintemp = new JLabel();
maxtemp = new JLabel();
link = new JLabel();
// Add to the mainPanel
mainPanel.add(text);
mainPanel.add(category);
mainPanel.add(mintemp);
mainPanel.add(maxtemp);
//Add mainPanel to Frame
add(mainPanel);
The above written code does the following,
mainPanel = new JPanel(new GridLayout(4, 1)); This line of code set GridLayout as the layout of mainPanel. GridLayout is a type of layout manager which divides the container(mainPanel) in to equal number of grids by dividing it into rows and columns.
In the given code I have divided the mainPanel into 4 rows and 1 columns, so total 4 grids.
mainPanel.add(text);
mainPanel.add(category);
mainPanel.add(mintemp);
mainPanel.add(maxtemp);
This bunch of code add the swing components to the mainPanel. When the first line of code is executed, the text label is added to mainPanel in first grid. Similarly, second line add category to the second grid and similar for the rest.
add(mainPanel); This line of code adds mainPanel to the Frame.
If you executed the above code, the output will be similar to,
Note : I have changed the text of the labels as shown in above image.

Related

Fixed height and width for JTextField

I've been working with Java Swing recently and when I try to add 3 JTextFields beneath each other they fill out the whole JFrame. But I want them to have a fixed height and width. What can I do?
Since I'm new to this topic I wasn't able to try out many things. I haven't found anything in other forums either.
My goal was to make a simple GUI for Users to fill in their credentials. Those credentials should be filled into an array but I haven't got there yet.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class PeopleGUI extends JFrame{
JPanel jp = new JPanel();
JLabel jl = new JLabel();
JTextField jt = new JTextField(30);
JTextField jt1 = new JTextField(30);
JTextField jt2 = new JTextField(30);
JButton jb = new JButton("Enter");
public PeopleGUI(){
setTitle("PeopleGUI");
setVisible(true);
setSize(400,200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
jp.add(jt);
jp.add(jt1);
jp.add(jt2);
jt.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String input = jt.getText();
jl.setText(input);
}
});
jp.add(jb);
jb.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String input = jt.getText();
jl.setText(input);
}
});
jp.add(jl);
add(jp);
}
public static void main(String[] args) {
PeopleGUI p = new PeopleGUI();
}
}
I expect JTextFields that don't adjust to the size of the window.
Currently, it is looking like this:
.
But it should rather look like:
.
That layout is easily reproduced by putting 3 panels, each with a centered FlowLayout, into a single column GridLayout.
The important part is the FlowLayout, which will respect the preferred size of the components it is displaying.
Combinations of different layouts are often used when making a GUI. The idea is for each to handle a small part of the layout needs of the entire user interface. Here is a screenshot from that answer which lists the layouts used, by way of titled borders for each one.
But I think it would be better if the RHS of the label and the LHS of the fields are aligned vertically. To do that, use a single GridBagLayout.
You have to use a Layout e.g. BoxLayout. You will find some documentation here

Improper use of JTextField (maybe) Help creating a GUI

I'm very new to Java and I'm trying to create a small program that reverses text (That part I've figured out).
Where I'm getting stuck on is my GUI, my envisioned plan for the gui is a window with a centered text field for user input then under it in the directly middle of the window a button that reverses the text from the above text box and outputs it in a text box below the button.
Right now I'm using JTextField boxes and after trying to make them look the way I want I'm getting the feeling that there's an easier way to do it, but I don't know it.
Here's my GUI class:
public class ReverseTextGUI extends ReverseRun implements ActionListener {
public static JFrame frame;
private JPanel northFlowLayoutPanel;
private JPanel centerFlowLayoutPanel;
private JPanel southFlowLayoutPanel;
private final JButton reverse = new JButton("Reverse");
private final JTextField userInput = new JTextField(50);
private final JTextField reverseOutput = new JTextField(50);
public void actionPerformed(ActionEvent e) {
reverse.addActionListener((ActionListener) reverse);
reverse.setActionCommand("Reverse");
if ("algorithm".equals(e.getActionCommand())) {
System.out.println("test");
}
}
public void initUI() {
northFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
northFlowLayoutPanel.add(userInput);
userInput.setPreferredSize(new Dimension(150,100));
centerFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
centerFlowLayoutPanel.add(reverse);
southFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
southFlowLayoutPanel.setBorder(BorderFactory.createTitledBorder("Output text"));
southFlowLayoutPanel.add(reverseOutput);
reverseOutput.setPreferredSize(new Dimension(150,100));
JFrame frame = new JFrame("Backwardizer");
frame.setLayout(new BorderLayout()); // This is the default layout
frame.add(northFlowLayoutPanel, BorderLayout.PAGE_START);
frame.add(centerFlowLayoutPanel, BorderLayout.CENTER);
frame.add(southFlowLayoutPanel, BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setSize(750, 500);
}
Any ideas how to either move the cursor to the start of the box (it shows up in the middle as of now) or a better way to accomplish what I'm trying to do?
For the reversing aspect, you can add the text from the first box to a string builder
StringBuilder rev = new StringBuilder(firstBox.getText());
String reversedText = rev.reverse().toString();
secondBox.setText(reversedText);
Something along those line should get the desired result if you nest it in the button action.
Any ideas how to either move the cursor to the start of the box (it shows up in the middle as of now) or a better way to accomplish what I'm trying to do?
JTextField#setCaretPosition, call this AFTER you've updated the text of the field
Make the field readonly, JTextField#setEditable and pass it false
Additionally, you could use a JList or JTextArea if you want to store multiple rows/lines of text
You should also avoid using setPreferredSize, see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more details

How to remove the padding between in the JPanel still using a flow layout?

Here's the portion of my java application GUI that I have a question about.
What this GUI consists is a blue JPanel(container) with default FlowLayout as LayoutManager that contains a Box which contains two JPanels(to remove the horizontal spacing or i could have used setHgaps to zero for that matter instead of a Box) that each contains a JLabel.
Here's my code for creating that part of the GUI.
private void setupSouth() {
final JPanel southPanel = new JPanel();
southPanel.setBackground(Color.BLUE);
final JPanel innerPanel1 = new JPanel();
innerPanel1.setBackground(Color.ORANGE);
innerPanel1.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
innerPanel1.add(new JLabel("Good"));
final JPanel innerPanel2 = new JPanel();
innerPanel2.setBackground(Color.RED);
innerPanel2.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
innerPanel2.add(new JLabel("Luck!"));
final Box southBox = new Box(BoxLayout.LINE_AXIS);
southBox.add(innerPanel1);
southBox.add(innerPanel2);
myFrame.add(southPanel, BorderLayout.SOUTH);
}
My question is how would i get rid the vertical padding between the outer JPanel(the blue one) and the Box?
I know this is padding because i read on Difference between margin and padding? that "padding = space around (inside) the element from text to border."
This wouldn't work because this has to due with gaps(space) between components.- How to remove JPanel padding in MigLayout?
I tried this but it didn't work either. JPanel Padding in Java
You can just set the gaps in the FlowLayout, i.e.
FlowLayout layout = (FlowLayout)southPanel.getLayout();
layout.setVgap(0);
The default FlowLayout has a 5-unit horizontal and vertical gap. Horizontal doesn't matter in this case as the BorderLayout is stretching the panel horizontally.
Or simple initialize the panel with a new FlowLayout. It'll be the same result.
new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
Edit:
"I tried that, didn't work.."
Works for me...
Setting the gap ↑ Not setting the gap ↑
import java.awt.*;
import javax.swing.*;
public class Test {
public void init() {
final JPanel southPanel = new JPanel();
FlowLayout layout = (FlowLayout)southPanel.getLayout();
layout.setVgap(0);
southPanel.setBackground(Color.BLUE);
final JPanel innerPanel1 = new JPanel();
innerPanel1.setBackground(Color.ORANGE);
innerPanel1.add(new JLabel("Good"));
final JPanel innerPanel2 = new JPanel();
innerPanel2.setBackground(Color.RED);
innerPanel2.add(new JLabel("Luck!"));
final Box southBox = new Box(BoxLayout.LINE_AXIS);
southBox.add(innerPanel1);
southBox.add(innerPanel2);
southPanel.add(southBox); // <=== You're also missing this
JFrame myFrame = new JFrame();
JPanel center = new JPanel();
center.setBackground(Color.yellow);
myFrame.add(center);
myFrame.add(southPanel, BorderLayout.SOUTH);
myFrame.setSize(150, 100);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setLocationByPlatform(true);
myFrame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Test().init();
}
});
}
}
Note: Always post a runnable example (as I have done) for better help. You say it doesn't work, but it always works for me, so how would we know what you're doing wrong without some code that will run and demonstrate the problem?

Struggling with the append method for JTextArea

This is the code I am struggling with. It is refusing to amend the JTextArea with the new text. I create the window and set it to visible in the main function of the project.
Thanks ahead.
EDIT:
By refusing, I mean the JTextArea will simply not display the text. It just stays empty. I'm not getting and error or exception. It is all logical.
class Window extends JFrame{
protected JTextArea text;
public Window() {
setTitle("Create a list of names");
setSize(500,400);
Container containerPane = getContentPane();
JPanel jp = new JPanel();
text = new JTextArea(10,50);
text.setPreferredSize(new Dimension(256,256) );
text.setEditable(false);
JScrollPane scrollText = new JScrollPane(text);
scrollText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jp.add(scrollText);
containerPane.add(jp, BorderLayout.CENTER);
text.append("Test");
}
public static void main(String[] args) {
Window w = new Window();
w.setVisible(true);
}
}
The column width of 50 is greater than the width of the frame so the added text appears offscreen. Reduce its value to fit the parent window
textArea = new JTextArea(10, 35);
Don't use setPrerredSize. Let the layout manager do its job and call pack after all components have been added.

Java Swing - JTable not showing

I'm having some troubles with Java Swing.
I'm trying to make a frame with a control panel at the top with some buttons in it.
and below that i want a JTable to show
I've been trying but the table is not showing.
If I remove the controlPanel at the top, it sometimes shows and sometimes not.
The code that I use inside my constructor of my JTable is provided in the same application,
so it's no network error
public ServerMainFrame(GuiController gc){
this.gc = gc;
initGUI();
}
private void initGUI() {
System.out.println("initiating GUI");
createFrame();
addContentPanel();
addControls();
//openPopUpServerSettings();
addSongTable();
}
private void createFrame()
{
this.setTitle("AudioBuddy 0.1");
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800, 600);
this.setResizable(false);
this.setLocationRelativeTo(null);
}
private void addContentPanel()
{
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
p.setSize(new Dimension(800, 600));
this.setContentPane(p);
}
private void addControls()
{
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
controlPanel.setBorder(BorderFactory.createLineBorder(Color.black));
controlPanel.setSize(700,100);
// Buttons
JButton play = new JButton("Play");
JButton pause = new JButton("Pause");
JButton stop = new JButton ("Stop");
JButton next = new JButton("Next");
JButton prev = new JButton("Previous");
controlPanel.add(play);
controlPanel.add(pause);
controlPanel.add(stop);
controlPanel.add(next);
controlPanel.add(prev);
// Currently playing
JLabel playing = new JLabel("Currently playing:");
controlPanel.add(playing);
JLabel current = new JLabel("Johnny Cash - Mean as Hell");
controlPanel.add(current);
this.getContentPane().add(controlPanel);
}
private void addSongTable()
{
JTable songTable = new JTable(Server.getSongTableModel());
songTable.setVisible(true);
JPanel tablePanel = new JPanel();
tablePanel.setVisible(true);
tablePanel.add(songTable);
songTable.repaint();
this.getContentPane().add(tablePanel);
JButton btnMulticastList = new JButton("send list to clients");
btnMulticastList.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Server.MulticastPlaylist();
}
});
getContentPane().add(btnMulticastList);
}
if I remove the controlPanel at the top, it sometimes shows and
sometimes not.
everything is hidden in Server.getSongTableModel(), nobody knows without posting an SSCCE with hardcoded value returns from
GUI has issue with Concurency in Swing
XxxModel loading data continiously with building GUi, then exception caused described problems
The code that I use inside my constructor of my JTable is provided in
the same application, so it's no network error
no idea what you talking about
have to create an empty GUI, see InitialTread
showing GUI, then to start loading data to JTable
then starting Workers Thread (Backgroung Task) from SwingWorker or (descr. Network issue) better Runnable#Thread (confortable for catching an exceptions and processing separate threads)
output from Runnable to the Swing GUI must be wrapped into invokeLater()
If you want controls at the top of your window, and the table filling the majority of the window, then I'd suggest you try using BorderLayout instead of FlowLayout. Create it like this...
private void addContentPanel()
{
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.setSize(new Dimension(800, 600));
this.setContentPane(p);
}
And add the components by specifying the location in the BorderLayout. In this case, the controls should be added to the top in their minimal size...
this.getContentPane().add(controlPanel,BorderLayout.NORTH);
And the table should be in the center, filling the remaining window space...
this.getContentPane().add(tablePanel,BorderLayout.CENTER);
In your case, you also have a button at the bottom...
getContentPane().add(btnMulticastList,BorderLayout.SOUTH);
For the layout you're after, BorderLayout is much more appropriate. The benefit of using BorderLayout here is that the components should be automatically resized to the size of the window, and you're explicitly stating where each component resides, so panels shouldn't not appear.
It would also be my recommendation that you find an alternative to calling getContentPane() in all your methods. Maybe consider keeping a global variable for the main panel, like this...
private mainPanel;
private void addContentPanel()
{
mainPanel = new JPanel(new BorderLayout());
mainPanel.setSize(new Dimension(800, 600));
this.setContentPane(mainPanel);
}
Then you can reference the panel directly when you want to add() components to it.
Finally, I'd also suggest using GridLayout for your controls, as it will allow you to place all your buttons in it, and they'll be the same size for consistency. Define it like this to allow 5 buttons in a horizontal alignment...
JPanel controlPanel = new JPanel(new GridLayout(5,1));
then you just add the buttons normally using controlPanel.add(button) and they'll be added to the next slot in the grid.
For more information, read about GridLayout or BorderLayout, or just see the Java Tutorial for a Visual Guide to Layout Managers to see what alternatives you have and the best one for your situation. In general, I try to avoid FlowLayout, as I find that there are other LayoutManagers that are more suitable in the majority of instances.

Categories

Resources