Does anyone see an issue with my code that might prevent JTextArea to become scrollable when you query data which expands it's bounds, it also seems that some words are getting cut in half, but the JScrollPane, which is supposedly supposed to fix the issue is failing at doing so.
package guiprojj;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import javax.swing.*;
import com.eclipsesource.json.JsonObject;
import com.google.gson.JsonParser;
import com.json.parsers.JSONParser;
import com.json.parsers.JsonParserFactory;
public class gui {
public static void main(String[] args)
{
JFrame maingui = new JFrame("Gui");
JButton enter = new JButton("Enter");
final JTextArea movieinfo = new JTextArea(5,20);
final JTextField movietext = new JTextField(16);
final JScrollPane scrolll = new JScrollPane(movieinfo);
JPanel pangui = new JPanel();
pangui.add(movietext);
pangui.add(enter);
scrolll.add(movieinfo);
pangui.add(movieinfo);
maingui.setResizable(false);
maingui.setVisible(true);
movieinfo.setLineWrap(true);
movieinfo.setEditable(false);
maingui.add(pangui);
scrolll.getPreferredSize();
//pangui.setPreferredSize(new Dimension(300, 150));
//pangui.add(scrolll, BorderLayout.CENTER);
//movieinfo.add(scrolll);
maingui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
maingui.pack();
enter.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.out.println(Test.getMovieInfo(movietext.getText()));
JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonData=parser.parseJson(Test.getMovieInfo(movietext.getText()));
String Title = (String)jsonData.get("Title");
String Year = (String)jsonData.get("Year");
String Plot = (String)jsonData.get("Plot");
movieinfo.setText("Title: "+Title+"\nYear: "+ Year +"\nPlot: "+Plot);
}
});
}
}
final JTextArea movieinfo = new JTextArea(5,20);
final JScrollPane scrolll = new JScrollPane(movieinfo);
JPanel pangui = new JPanel();
//scrolll.add(movieinfo);
//pangui.add(movieinfo);
pangui.add(scroll);
A component can only have a single parent. You create the scrollpane with the text area which is good. But then you add the textarea to the panel, which is bad since the text area gets removed from the scrollpane).
You need to add the scrollpane to the panel since this is the component that contains the text area.
I think you should use a ScrollPane.
JTextArea ta = new JTextArea();
JScrollPane sp = new JScrollPane(ta);
Related
Hello StackExchange community,
I'm at my wits end about this JSplitPane I'm trying to put into my frame, it is sitting on the right side of my frame instead of filling it up or atleast sitting on the left.
If anyone could help me with this issue I'd be very thankful.
See below an image of my problem and the code
The problem area is the pane with "tab1" and "tab2", the divider and the pane on the right side of that divider:
I've tried setting setAlignmentX(Component.LEFT_ALIGNMENT) on all the individual parts of the JSplitPane. I've also tried making a JPanel to hold it and aligning that. All to no avail.
Furthermore, existing information I've been able to find hasn't been relevant, mostly people discussing how to align the contents of the JSplitPane.
The code below is all that is needed to make this frame, if any of you need it to help me out feel free.
package test;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
public class FrameMaker {
public int x = 0;
private ArrayList<String> mpLabels;
private JFrame theFrame;
public void MakeFrame() {
theFrame = new JFrame("title");
theFrame.getContentPane().setLayout(new BoxLayout(theFrame.getContentPane(), BoxLayout.Y_AXIS));
mpLabels = new ArrayList<String>();
//label1
JPanel bgSwitches = new JPanel();
JLabel calcsLabel = new JLabel("top label, broadened with lines to exaggerate problem-------------------------------------------");
bgSwitches.add(calcsLabel);
//label2
JPanel topLevel = new JPanel();
JLabel textinfo = new JLabel("label below that");
topLevel.add(textinfo);
//splitpane tabs
mpLabels.add("tab1");
mpLabels.add("tab2");
String[] mpLabelsAr = new String[mpLabels.size()];
JList<String> posL = new JList<String>(mpLabels.toArray(mpLabels.toArray(mpLabelsAr)));
posL.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//panel inside the right splitpane pane, this is needed for something later.
JPanel RPanel = new JPanel();
RPanel.setLayout(new BoxLayout(RPanel, BoxLayout.Y_AXIS));
JScrollPane scrollPos = new JScrollPane(posL);
JScrollPane scrollROI = new JScrollPane(RPanel);
JSplitPane posPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,scrollPos,scrollROI);
posPanel.setOneTouchExpandable(false);
posPanel.setDividerLocation(75);
//label and textfield
JLabel msLabel = new JLabel("another label");
JTextField msField = new JTextField("textfield");
JPanel buttonPanel = new JPanel();
buttonPanel.add(msLabel);
buttonPanel.add(msField);
bgSwitches.setBackground(new Color(0,0,255));
theFrame.add(bgSwitches);
topLevel.setBackground(new Color(0,255,0));
theFrame.add(topLevel);
posPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
posPanel.setBackground(new Color(0,255,255));
theFrame.add(posPanel);
buttonPanel.setBackground(new Color(255,0,0));
theFrame.add(buttonPanel);
theFrame.pack();
theFrame.setVisible(true);
}
}
You need to align all of your other elements to the left as well.
bgSwitches.setAlignmentX(Component.LEFT_ALIGNMENT);
topLevel.setAlignmentX(Component.LEFT_ALIGNMENT);
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
You can also add posPanel.setResizeWeight(VALUE BETWEEN 0 AND 1); to specify what percent of the space the JSplitPane should occupy and it will resize with your window.
I'm having a very hard time with borders, I've looked through tutorials and examples and each seems to use a different style, I'm just trying to organise the content into separated borders. The content for the bottom panal isn't finished yet but I'm just trying to get it to work as is before adding more.
The compiler says there are problems on two lines java.lang.NullPointerException:
package question2;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
/**
* #author Matt Headley
This frame shows a data set and its statistics.
*/
public class ComputerStoreGUI extends JFrame
{
private JCheckBox item1;
private JCheckBox item2;
private JCheckBox item3;
private JCheckBox item4;
private JCheckBox item5;
private TitledBorder border;
private TitledBorder border2;
private static JPanel content;
private static JPanel top;
private static JPanel bottom;
private JTextField parts;
public ComputerStoreGUI()
{
JCheckBox item1 = new JCheckBox("Install Hard Drive - $25.00");
JCheckBox item2 = new JCheckBox("Install RAM - $15.00");
JCheckBox item3 = new JCheckBox("Remove Virus - $50.00");
JCheckBox item4 = new JCheckBox("Format Hard Drive - $80.00");
JCheckBox item5 = new JCheckBox("Quote Hourly Labour - $10.00");
item1.setHorizontalAlignment(JCheckBox.LEFT);
item2.setHorizontalAlignment(JCheckBox.LEFT);
item3.setHorizontalAlignment(JCheckBox.LEFT);
item4.setHorizontalAlignment(JCheckBox.LEFT);
item5.setHorizontalAlignment(JCheckBox.LEFT);
JTextField cost = new JTextField(10);
top = new JPanel(new FlowLayout(FlowLayout.LEFT));
top.add(item1);
top.add(item2);
top.add(item3);
top.add(item4);
top.add(item5);
bottom.add(cost); //here ????????
cost.setHorizontalAlignment(JTextField.CENTER);
}
public static void main(String[] args)
{
JFrame frame = new ComputerStoreGUI(); // and here ???????
content = new JPanel();
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
top = new JPanel();
top.setBorder(BorderFactory.createTitledBorder("Standard Services"));
bottom = new JPanel();
bottom.setBorder(BorderFactory.createTitledBorder("Hourly Service"));
frame.setSize(250, 400);
frame.setTitle("LU Computer Store");
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content.add(top);
content.add(bottom);
frame.setVisible(true);
}
}
the end goal is to look something like this:
First, I dont see a reson to extend JFrame in your example. So without inheritance you can use composition like:
JFrmae frame = new JFrame();
Read more: Why do we need to extend JFrame in a swing application?
The compiler says there are problems on two lines
java.lang.NullPointerException:
Reason is, you have declared the JPanel bottom but without initializing you are trying to use it, from this line: bottom.add(cost);
Do something like:
bottom = new JPanel(new FlowLayout(FlowLayout.LEFT));
bottom.add(cost);
EDIT:
comment: It runs now, but the panels are tiny
Because you need to set layout for the parent JPanel, you can use BoxLayout, to add child panels one below another, like below:
content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
In case if you want to add space between those two child panels, use as below:
content.add(top);
content.add(Box.createRigidArea(new Dimension(0,10)));
content.add(bottom);
I am writing some Java code that allows the user to see a frame with JLabel, JTextField and JButton.
I want the JLabel to be called "Count" and I have a problem with FlowLayout.
I want the interface to look like this:
Instead, I have this:
This is my code:
package modul1_Interfate_Grafice;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Exercitiu04 implements ActionListener {
private JFrame frame;
private JLabel labelCount;
private JTextField tfCount;
private JButton buttonCount;
private int count = 0;
public void go() {
frame = new JFrame("Java Counter");
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
frame.getContentPane().add(BorderLayout.CENTER, labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
labelCount.add(tfCount);
buttonCount = new JButton("Count");
labelCount.add(buttonCount);
buttonCount.addActionListener(this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350, 150);
frame.setLocation(400, 200);
}
#Override
public void actionPerformed(ActionEvent event) {
count++;
tfCount.setText(count + "");
}
public static void main(String[] args) {
Exercitiu04 a = new Exercitiu04();
a.go();
}
}
Solve it.
Instead of labelCount.setLayout(new FlowLayout());` i should have had
frame.setLayout(new FlowLayout());
From description of JLabel class,
JLabel is:
A display area for a short text string or an image, or both.
But here: labelCount.add(tfCount) and here labelCount.add(buttonCount) you're trying to put a textfield and a button into a label. In this case, positions of button and textfield are controlled by FlowLayout but position of the text in the label is not.
Instead of this, you should put all of your elements in common JPanel, like this:
...
frame = new JFrame("Java Counter");
frame.setLayout(new BorderLayout());
JPanel wrapper = new JPanel(); // JPanel has FlowLayout by default
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
wrapper.add(labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
wrapper.add(tfCount);
buttonCount = new JButton("Count");
buttonCount.addActionListener(this);
wrapper.add(buttonCount);
frame.add(BorderLayout.CENTER, wrapper);
...
And, like MasterBlaster said, you should put swing methods in EDT.
There are only two things you should know about FlowLayout:
a) It is a default layout manager of the JPanel component
b) It is good for nothing.
This trivial layout cannot be achieved with FlowLayout.
When doing layouts in Swing, you should familiarize yourself
with some powerful layout managers. I recommend MigLayout and
GroupLayout.
package com.zetcode;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
/*
Simple UI with a MigLayout manager.
Author Jan Bodnar
Website zetcode.com
*/
public class MigLayoutCounterEx extends JFrame {
public MigLayoutCounterEx() {
initUI();
}
private void initUI() {
JLabel lbl = new JLabel("Counter");
JTextField field = new JTextField(10);
JButton btn = new JButton("Count");
createLayout(lbl, field, btn);
setTitle("Java Counter");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
setLayout(new MigLayout());
add(arg[0]);
add(arg[1]);
add(arg[2]);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MigLayoutCounterEx ex = new MigLayoutCounterEx();
ex.setVisible(true);
});
}
}
The example is trivial. You just put the three components into the
cells.
Screenshot:
You shouldn't use setSize when dealing with FlowLayout. Instead use pack(). It makes the window just about big enough to fit all your components in. That should tidy things up for you
My adventure game has a bunch of nested if statements to output something based on the input, but my JTextField only gets one input and then disappears. I want to get the JTextField to take unlimited inputs and use .append to to show them in the jtextarea. I want to have the program continue to take user inputs until the story path in the if statements end. If want to get input from a JTextField and put the output in the JTextArea and keep it there.
import java.awt.Dimension;
import java.awt.Font;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.util.Scanner;
import java.io.Reader;
import javax.swing.*;
import javax.swing.text.BadLocationException;
/*JakeBarcelona
*Date:May 5, 2016
*Program Name:StoryTester.java
*Description:
*/
public class StoryTester extends JFrame
{
static JTextField input = new JTextField(30);
static JTextArea fields = new JTextArea(30,50);
static Story ARoom=new Story();
public static void main(String[] args) throws BadLocationException
{
JFrame frame = new JFrame();
String story=new String();
JLabel intro = new JLabel(story);
//Sets the JLabels font and color
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//puts a red x to close it
Story wow = new Story();
String introduction=wow.intro();
//creates array field for text editing
fields.insert(introduction, 0);
String name= fields.getText(0,30);
//creates new Panel
JPanel myPanel=new JPanel();
//creates label for text box
myPanel.setPreferredSize(new Dimension(600,600));
myPanel.add(fields);
myPanel.add(input);
//puts a scroll bar and cancel and ok button
JScrollPane scroll = new JScrollPane(fields, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
myPanel.add(scroll);
int result = JOptionPane.showConfirmDialog(null, myPanel, "Story", JOptionPane.OK_CANCEL_OPTION);
if(result==JOptionPane.OK_OPTION);
{
String jake = input.getText();
String need = ARoom.storyStatements(jake);
System.out.println(need);
fields.append(need);
}
}
}
You are adding fields twice to the GUI, once to myPanel and once to the JScdrollPane, scrool, which is then added to myPanel. Don't do this, but rather add it to the JScrollPane only. You're also artificially constraining the size of your myPanel JPanel, and this is likely what's getting you into trouble.
Instead use layouts in a smart way by for instance giving myPanel a BorderLayout, adding the JScrollPane to the BorderLayout.CENTER position and the inputs JTextField to the BorderLayout.PAGE_END position. And don't set the preferred size of myPanel but rather let the text component column and row properties set their preferred size which will in turn set the preferred size of the myPanel JPanel.
Also you're using static fields inappropriately and in fact none of your current fields should be static.
For example
import java.awt.BorderLayout;
import javax.swing.*;
public class LayoutEg extends JPanel {
private static final int COLS = 50;
private static final int ROWS = 30;
private JTextField input = new JTextField(COLS);
private JTextArea fields = new JTextArea(ROWS, COLS);
public LayoutEg() {
// two methods below so that words wrap
fields.setWrapStyleWord(true);
fields.setLineWrap(true);
fields.setFocusable(false); // so we can't write directly into JTextArea
JScrollPane scrollPane = new JScrollPane(fields);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
setLayout(new BorderLayout(2, 2));
add(scrollPane, BorderLayout.CENTER);
add(input, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
LayoutEg mainPanel = new LayoutEg();
JFrame frame = new JFrame("Story GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Hi this is a bit of a basic question. In my code I create a gui in a constructor then nest a ActionListener class to handle button changes. This code will create the gui and the action listener runs through the actionPerformed method correctly. However, I've tried multiple ways to change the panel in the gui but I feel like the way I have the program set up it is not possible for this to work. Sorry if this is a repeat but after searching for a while on S.O. I haven't found a good example that would help me with my problem.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import org.math.plot.Plot2DPanel;
import org.math.plot.plotObjects.BaseLabel;
public class GraphGui extends JFrame {
//default width and height of the GUI
private static final int WIDTH = 1200;
private static final int HEIGHT = 700;
GraphPlot gp = new GraphPlot();
Plot2DPanel plotPanel =gp.determinePlotToPlot("duration");
/**
* This is the constructor that initializes the JFrame and the layout of the GUI.
* The radio buttons are also created here and grouped accordingly.
*/
public GraphGui() {
//title of GUI
setTitle("VibeTech Graph Gui");
//First JRadioButton for date vs duration
JRadioButton durToDate = new JRadioButton("Duration vs. Date");
durToDate.addActionListener(new RadioButtonListener());
durToDate.setActionCommand("duration");
durToDate.setSelected(true);
//JRadioButton for weight vs date
JRadioButton weightToDate = new JRadioButton("Weight vs. Date");
weightToDate.addActionListener(new RadioButtonListener());
weightToDate.setActionCommand("weight");
//JRadioButton for plan type vs date
JRadioButton planToDate = new JRadioButton("Plan vs. Date");
planToDate.addActionListener(new RadioButtonListener());
planToDate.setActionCommand("level");
//button group of the buttons to display them as one group
ButtonGroup group = new ButtonGroup();
group.add(planToDate);
group.add(weightToDate);
group.add(durToDate);
//create JPanel to add objects to
JPanel jplRadio = new JPanel();
jplRadio.setLayout(new GridLayout(0, 1));
//add radio buttons
jplRadio.add(planToDate);
jplRadio.add(weightToDate);
jplRadio.add(durToDate);
Plot2DPanel dvt = new Plot2DPanel();
dvt.addLinePlot("Duration over Time", gp.getDate(), gp.getDuration());
BaseLabel title = new BaseLabel("Duration over Time", Color.RED,
0.5, 1.1);
title.setFont(new Font("Courier", Font.BOLD, 20));
dvt.addPlotable(title);
dvt.setAxisLabels("Time", "Duration");
setLayout(new BorderLayout());
add(jplRadio, BorderLayout.WEST);
add(plotPanel, BorderLayout.EAST);
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//main method to run program
public static void main(String [ ] args)
{
//create new GUI
#SuppressWarnings("unused")
GraphGui test = new GraphGui();
}
//create a radio button listener to switch graphs on button press
class RadioButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("duration")) {
plotPanel = gp.determinePlotToPlot("duration");
} else if (e.getActionCommand().equals("weight")) {
plotPanel = gp.determinePlotToPlot("weight");
} else if (e.getActionCommand().equals("level")) {
plotPanel = gp.determinePlotToPlot("level");
}
//here is where I tried to do removes, adds, and validates but
//I have trouble getting to the frame itself to remove the JPanel
//component. I think this is a setup problem.
}
}
}
You would need to add the panel and revalidate/repaint the JFrame for it to appear:
add(plotPanel, BorderLayout.EAST);
revalidate();
repaint();
Better to use CardLayout to manage this type of functionality.
Try using CardLayout for switching between panels. Here is my solution for a similar question: https://stackoverflow.com/a/9377623/544983