I am trying to make a UI to view recipes from a cookbook stored on the computer. Part of this tab is a JScrollPanel storing a JTextArea that displays the available recipes. All called functions work as intended (e.g. allRecipes() returns a string of the available recipes properly); however, the scroll pane itself does not appear. It is added to the frame, as I can see by a small grey block where the pane would be, but it is not filled as it should be. The code is as follows:
//First panel, buttons to limit displayed recipes
JPanel pane1 = new JPanel();
JButton all = new JButton("All");
JButton makeable = new JButton("Makeable");
JTextField search = new JTextField("", 10);
JButton searchButton = new JButton("Search Ingredient");
//Second panel, display of recipes
JPanel pane2 = new JPanel();
JTextArea recipes = new JTextArea(allRecipes());
JLabel list = new JLabel("List of Recipes:");
JScrollPane scroll = new JScrollPane(recipes);
//Third panel, options to add recipe and view specific recipe
JPanel pane3 = new JPanel();
JButton add = new JButton("Add Recipe");
JTextField view = new JTextField("", 10);
JButton viewButton = new JButton("View Recipe");
//Central method
public Recipes() {
//basic UI stuff
super("Recipes");
setSize(475,350);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
FlowLayout flo = new FlowLayout();
setLayout(flo);
//add pane 1
pane1.add(all);
pane1.add(makeable);
pane1.add(search);
pane1.add(searchButton);
pane1.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
add(pane1);
//add pane 2
pane2.add(list);
scroll.setPreferredSize(new Dimension(10,15));
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane2.add(scroll, BorderLayout.CENTER);
pane2.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
add(pane2);
//add pane 3
pane3.add(add);
pane3.add(view);
pane3.add(viewButton);
add(pane3);
//start up the UI
setVisible(true);
}
JTextArea recipes = new JTextArea(allRecipes());
We don't know what allRecipes() does, but I would guess it sets the text of the text area.
Instead you should define your text area with the rows/columns you wish. Something like:
JTextArea recipes = new JTextArea(5, 30);
then in the constructor you would add the text:
recipes.setText( allRecipes() );
You should NOT be trying to set the preferred size of the scroll pane. The preferred size will automatically be determined from the preferred size of the text area which is calculated based on the rows/columns provided in the constructor.
//scroll.setPreferredSize(new Dimension(10,15));
Also, the preferred size of a component is specified in pixels, to the above makes no sense.
pane2.add(scroll, BorderLayout.CENTER);
The default layout manager for a JPanel is the FlowLayout. So you can't just use a BorderLayout constraint when adding the component.
Related
I have written a java gui code for many options available on it. the gui is also set visible true but it doesn't show until I pick its border and drag them to resize the gui window. After manually resizing it, it shows everything. Also, the textlabels and the textfields and buttons are not in new lines, they are placed one after one. Please tell me whats wrong with that: here is a part of code:
public static void initGUI(){
JFrame fr = new JFrame();
Container cont = fr.getContentPane();
cont.setLayout( new FlowLayout( ) );
FlowLayout layout = new FlowLayout();
cont.setLayout(layout);
frame.setSize(200,300) ;
frame.setVisible(true) ;
JTextField tName = new JTextField(30);
JTextField tCNIC = new JTextField(15);
JLabel nameLabel = new JLabel("Name:");
JLabel cnicLabel = new JLabel("CNIC #:");
cont.add(nameLabel);
cont.add(tName);
cont.add(cnicLabel);
cont.add(tCNIC);
JButton Cancel = new JButton ("Canel" );
JButton OK = new JButton ("OK" );
savebtn.setPreferredSize(new Dimension(150, 50));
retbtn.setPreferredSize(new Dimension(150, 50));
cont.add(savebtn);
cont.add(retbtn);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
frame.setVisible(true) ;
The above statement should be invoked AFTER all the components have been added to the frame. So it should be the last statement in your method.
Also, you should be invoking:
frame.pack();
instead of setSize(), before making the frame visible so all the components are displayed at their preferred size.
frame.setVisible(true);
This Statement should be invoked in the last of adding other components to the Frame.
(using netbeans)
So for my project I need to add a JscrollPane so that the user can see all of the JTextArea output, a piechart and the two buttons I have added. This is the code I have implementing the JscrollPane. However it is causing the program to no longer produce an output screen. My question is do I need to add the JscrollPane to the JPanel or to the JFrame and if so what am I doing wrong (tried to include as much of the code as I thought was relevant)
P.S Should I change from Borderlayout to a Boxlayout? Would that make a difference in terms of adding a jscroll?
JFrame frame1 = new JFrame("Portfolio Results");
frame1.setSize(800,800);
// frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// output screen declartions
frame1.setLayout(new BorderLayout());
JPanel panel1 = new JPanel();
frame1.add(panel1,BorderLayout.PAGE_START);
panel1.setLayout(new BorderLayout());
JTextArea area1 = new JTextArea();
area1.setPreferredSize(new Dimension(600,600));
panel1.add(area1,BorderLayout.PAGE_START);
JScrollPane scp1 = new JScrollPane(frame1,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
frame1.add(scp1);
//code for Pie chart and two button
DefaultPieDataset piedata = new DefaultPieDataset();
piedata.setValue("test", new Integer (100));
JFreeChart chart = ChartFactory.createPieChart("test", piedata, true, true, true);
PiePlot p = (PiePlot)chart.getPlot();
ChartPanel testpan = new ChartPanel(chart);
panel1.add(testpan,BorderLayout.CENTER);
JButton button= new JButton("SAVE");
// button.setPreferredSize(new Dimension(80,20));
// Listener listener = new Listener();
// button.addActionListener(this);
panel1.add(button,BorderLayout.PAGE_END);
JButton pbutton=new JButton("Print");
panel1.add(pbutton,BorderLayout.SOUTH);
You should init the JScrollPane with the object you want to scroll through.
In your example, it seems the JTextArea is the object you want, so:
JScrollPane scp1 = new JScrollPane(area1,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
From the Oracle docs:
JScrollPane(Component view)
Creates a JScrollPane that displays the contents of the specified component, where both horizontal and
vertical scrollbars appear whenever the component's contents are
larger than the view.
Also, see this Oracle example.
I have next part of code:
final JList<String> list = new JList<String>(strings);
list.setLayoutOrientation(JList.VERTICAL);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
/* Create scroll pane instance */
JScrollPane scroll = new JScrollPane(list) {
#Override
public Dimension getPreferredSize()
{
BookFrame frame = BookFrame.instance();
Container parent = getParent();
return new Dimension(frame.getWidth(), parent.getHeight() - parent.getComponent(parent.getComponentCount() - 1).getHeight() - 14);
}
};
/* Create button instance */
JButton button = new JButton("Add Directory");
/* Add new panel */
JPanel panel = new JPanel();
panel.add(scroll);
panel.add(button);
This code runs when program starts and sometimes button height is a normal value (ex. 15) but sometimes it's 0. I think the problem is with JScrollPane instance - it was created before JButton instance - but I can't synchronize. I tried also to add JButton button = ... before JScrollPane scroll = ... but it's not working too.
I'm newby in Java so please tell me what I do wrong.
I don't see any reason you need to override the getPreferredSize() method. I would guess this is the problem.
JScrollPane scroll = new JScrollPane(list)
I don't know what "list" is, but assuming you are using a JList then you can use:
list.setVisibleRowCount(...);
to indicate the number of rows for the size of the list. The scrollpane will then be that size and scrollbars will appear if needed.
I try to order my elements with Borderlayout since Gridlayout makes everything the same size.
What I see is this:
while manually resizing it, I can have the following
Here's part of my code
public InputPanel() {
tfield = new TextField("Search your terms here!");
add(tfield, BorderLayout.PAGE_START);
searchButton = new JButton("Search");
searchButton.addActionListener(this);
add(searchButton, BorderLayout.LINE_START);
clearButton = new JButton("Clear Text");
clearButton.addActionListener(this);
add(clearButton, BorderLayout.LINE_END);
resultsArea = new TextArea();
add(resultsArea, BorderLayout.PAGE_END);
}
It seems like it does not help in arranging. It's just like I have used FlowLayout.
How can I format it properly?
For BorderLayout you should be using NORTH, SOUTH, EAST, WEST and CENTER to place your components. To achive the above layout, you should create one panel that has FLOWLAYOUT, where you add the textfield, seachbutton and clear button. This panel will then be placed inside BorderLayout.NORTH. After this you place the JTextArea inside BorderLayout.NORTH
public InputPanel() {
JPanel topPanel = new JPanel(); // Create a new panel
topPanel.setLayout(FlowLayout()); //Left to right alignment is default for FlowLayout
//Add your textfield and buttons to the panel with flowlayout
tfield = new TextField("Search your terms here!");
topPanel.add(tfield);
searchButton = new JButton("Search");
searchButton.addActionListener(this);
topPanel.add(searchButton);
clearButton = new JButton("Clear Text");
clearButton.addActionListener(this);
topPanel.add(clearButton);
add(topPanel, BorderLayout.NORTH); // Add the panel containing the buttons and textfield in the north
resultsArea = new TextArea();
add(resultsArea, BorderLayout.CENTER); //Add the textarea in the Center
}
This gives me the below appearance:
Seems you have missed GridBagLayout, which is the number one choice for a truly flexible layout manager. With BorderLayout you can also achieve a lot, but only with many levels of nesting, and the code to build it is quite unmanageable.
I want to repeatedly take input from the user(probably using a button) via a JOptionPane(already done) and store the details in something(how about a dynamic object array) and display this information as a list in a scrollable JList.
MY CODE
import java.awt.GridLayout;
import javax.swing.*;
class Flight {
public static void main(String[] args) {
//Panel
JPanel panel = new JPanel(new GridLayout(7, 2,20, 20));
//Add textfields here
JTextField txtflightno = new JTextField(8);
JTextField txtmechanicalstatus = new JTextField(8);
JTextField txtmedicalstatus = new JTextField(8);
JTextField txtfuellevel = new JTextField(8);
JTextField txtweathercondition = new JTextField(8);
JTextField txtfrequency = new JTextField(8);
JTextField txtflightpath = new JTextField(8);
//Add labels here
JLabel lblflightno = new JLabel("Flight No : ");
JLabel lblmechanicalstatus = new JLabel("Mechanical Status:");
JLabel lblmedicalstatus = new JLabel("Medical Status:");
JLabel lblfuellevel = new JLabel("Fuel Level:");
JLabel lblweathercondition = new JLabel("Weather Condition:");
JLabel lblfrequency = new JLabel("Frequency:");
JLabel lblflightpath = new JLabel("Flight Path:");
//Adding flightno to panel
panel.add(lblflightno);
panel.add(txtflightno);
//Adding mechanicalstatus to the panel
panel.add(lblmechanicalstatus);
panel.add(txtmechanicalstatus);
//Adding medicalstatus to the panel
panel.add(lblmedicalstatus);
panel.add(txtmedicalstatus);
//Adding fuellevel to the panel
panel.add(lblfuellevel);
panel.add(txtfuellevel);
//Adding weathercondition to the panel
panel.add(lblweathercondition);
panel.add(txtweathercondition);
//Adding frequency to the panel
panel.add(lblfrequency);
panel.add(txtfrequency);
//Adding flightpath to the panel
panel.add(lblflightpath);
panel.add(txtflightpath);
panel.setBounds(0, 0, 800, 600);
int result = JOptionPane.showConfirmDialog(null, panel, "Flight Details",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
}
}
}
How must I do the storing of the plane details ? How must I implement a scrollable JList ? Any suggestions.
Many Thanks
As discussed in How to Use Lists, JList uses a list model as the source of data it displays. Just add your data to a DefaultListModel, and use it to construct your list.
DefaultListModel dlm = new DefaultListModel();
// add data
JList list = new JList(dlm);
panel.add(new JScrollPane(list));
To make the JList scrollable, simply embed it in a JScrollPane. Instead of
add(myList, constraints);
do
add(new JScrollPane(myList), constraints);
To extend the list, just get the JList's ListModel (using getListModel) and use add to add objects.
More on using ListModels in Sun's tutorial.
More on ScrollPane in the Tutorial, too.
You've to use the ActionListener of Button, that you've missed in the code snippet.
In the OK Option :
JList jlist = ...;
jlist.add(txtflightno.getText());
jlist.add(txtmechanicalstatus.getText());
jlist.add(txtmedicalstatus.getText());
....
....
&
add(new JScrollPanel(myList), constraints);
After this use validate method of Component to update the list with this new item.
But one thing you should remember is that list displays each item row-wise.
I suggest you to use JTable with which you can display your items in a meaningful way...