Issue with JScrollPane + JTree display after having it initialized - java

I have a simple swing App, that can manage a specific type of project with multiple JButton and that print the project tree on the bottom, see the screenshoot bellow when a project is opened in the App :
App screenshoot with project opened
The thing is when no project is opened I get something like this :
App screenshoot without project opened
The HMI is simple and looks like this :
public class Desktop extends JFrame implements ActionListener {
public Desktop() {
JButton newProject, generate, quit, bAddToClassPath, openProject, saveProject;
JPanel mainPanel;
JScrollPane jscrollpane;
super("MainWindow");
setLookAndFeel();
setSize(330, 440);
ParamMainPanel();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Desktop();
}
});
}
public static void ParamMainPanel() {
mainPanel = new JPanel(new FlowLayout());
// BUTTONS PARAM
newProject = new JButton("Nouveau projet");
generate = new JButton("Générer...");
quit = new JButton("Quitter");
openProject = new JButton ("Ouvrir projet");
saveProject = new JButton ("Sauvegarder");
bAddToClassPath = UIUtil.iconButton();
bAddToClassPath.setActionCommand("setCP");
bAddToClassPath.addActionListener(this);
mainPanel.add(bAddToClassPath);
newProject.addActionListener(this);
newProject.setActionCommand("newP");
generate.addActionListener(this);
generate.setActionCommand("gen");
quit.addActionListener(this);
quit.setActionCommand("qui");
openProject.addActionListener(this);
openProject.setActionCommand("openP");
saveProject.addActionListener(this);
saveProject.setActionCommand("save");
mainPanel.add(newProject);
mainPanel.add(generate);
mainPanel.add(openProject);
mainPanel.add(saveProject);
mainPanel.add(quit);
// PROJECT TREE
jscrollpane = new JScrollPane(new JTree());
jscrollpane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jscrollpane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
jscrollpane.setMinimumSize(new Dimension(50, 50));
jscrollpane.setLocation(4,61);
jscrollpane.setSize(306,322);
mainPanel.add(jscrollpane);
}
}
So what I want is at the App launch, instead of having the bad looking display JTree (into the jscrollpane) without project opened, having the same display with a project opened (white bloc) but without the project tree inside.
I can't figure how to do it, any ideas ?

Here the answer I found to resolve this display problem :
The FlowLayout used on my main panel somehow was preventing me from resizing my jscrollpane directly using setSize()
So I decided to have a secondary panel on my MainFrame secondMainPanel without specific layout using new JPanel(null);
I did add jscrollpaneon it, then I could resize it without problems to have a correct display.
I think there might be better way to fix it, but this one works.

Related

GUI won't open when button pressed (Java)

I am trying to open a GUI from my main GUI by pressing a button. When the button is pressed, this is executed:
WorkloadFactor wf = new WorkloadFactor();
wf.setVisible(true);
This doesn't open the WorkloadFactor GUI. I am confused by this because I have other GUIs that open this way without issue.
WorkloadFactor class works fine when I run it by itself but won't open when it is called by my main GUI. Below is my class without imports and stuff:
public class WorkloadFactor extends JPanel {
public WorkloadFactor() {
setLayout(new BorderLayout());
JTabbedPane tabbedPane = new JTabbedPane();
String[] tabnames = { "Zero", "One", "Two", "Three", "Four" };
for (int i = 0; i < tabnames.length; i++) {
tabbedPane.addTab(tabnames[i], createPane(tabnames[i]));
}
tabbedPane.setSelectedIndex(0);
JButton submit = new JButton("Submit All");
submit.setForeground(Color.RED);
add(tabbedPane, BorderLayout.CENTER);
add(submit, BorderLayout.SOUTH);
}
public JPanel createPane(final String t) {
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
//setContentPane(contentPane); I think this might be it?
contentPane.setLayout(null);
setBounds(100, 100, 531, 347);
//***** all the components I am including then add them like so
//******contentPane.add(checkbox1);
//****** contentpane.add(label1);
return contentPane;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Set Workload Factor Information");
frame.getContentPane().add(new WorkloadFactor());
frame.setBounds(100, 100, 531, 347);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
I have tried arranging things in so many ways, putting everything in the constructor and other changes but can't seem to find a reason why instantiating this WorkloadFactor class elsewhere and setting it visible won't work.
Does it have something to do with setContentPane(contentPane) vs contentPane.add(xxxx) and returning it?
Thank you for reading!
WorkloadFactor wf = new WorkloadFactor();
wf.setVisible(true);
To be blunt, this won't display anything. Please understand that WorkloadFactor extends JPanel and like all non-top level components must be placed into a container that is ultimately held by a top-level window in order to be displayed. Look at how you display it in your main method -- you first put it into a JFrame, and then display that JFrame. You must do the same thing if you want to display it on button press -- you need to put it into a JPanel or other container that is held by a JFrame or JDialog, or JOptionPane.
Make sure that you have properly registered the button on your main GUI which opens WorkLoadFactor GUI to an action listener.
Since you have not included code from your main GUI I can't confirm this is the issue. However it is a commonly overlooked issue.
Heres some suggestions from the Java documentation tutorials:
"Problem: I'm trying to handle certain events from a component, but the component isn't generating the events it should.
First, make sure you registered the right kind of listener to detect the events. See whether another kind of listener might detect the kind of events you need.
Make sure you registered the listener on the right object.
Did you implement the event handler correctly? For example, if you extended an adapter class, then make sure you used the right method signature. Make sure each event-handling method is public void, that the name spelled right and that the argument is of the right type."
source: Solving Common Event-Handling Problems
Make a JFrame and add a JButton in it than add action listener in button and add this code in it like this:
This code makes a frame with a button and when button is pressed new window is opened.
public class Example extends JFrame {
public Example() {
super("Title");
setLayout(new FlowLayout());
JButton b = new JButton("Open new Frame");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
newWindow nw = new newWindow();
}
});
add(b);
}
}
newWindow Code:
public class newWindow extends JFrame {
newWindow() {
super("title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setVisible(true);
}
}

Visualization issue of a simple GUI in Java

I did a very simple GUI in Java but when I run the program, the GUI acts wierd!
As soon as I run the application: the GUI shows like this:
Once I simply minimize it and get it back up, it shows fine, like this:
This is the very simple code:
public class Prova2 {
public static void main(String[] args) {
JFrame frame = new JFrame("A Simple GUI");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(650, 120);
frame.setLocation(430, 100);
JPanel panel = new JPanel();
frame.add(panel);
JLabel lbl = new JLabel("Select one of the possible choices and click OK");;
lbl.setVisible(true);
panel.add(lbl);
String[] choices = { "CHOICE 1","CHOICE 2", "CHOICE 3","CHOICE 4","CHOICE 5","CHOICE 6"};
JComboBox<String> cb = new JComboBox<String>(choices);
cb.setVisible(true);
panel.add(cb);
JButton btn = new JButton("OK");
panel.add(btn);
}
}
What am I missing in order to show the GUI fine (with all its element displayed) as soon as I run the application?
It's annoying having to necessarily minimize or resize the window in order to show the GUI properly!
I tested your code and the problem is you are setting the visibility on true before you create the items inside your JFrame. So just cut the frame.setVisible(true); and paste it as the last line of the constructor.
also I see you aren't using a layout manager which is heavy recommended. Check this for information.
Use layout manager
Follow a main Swing Toolkit principle: all UI should be manipulated and started on EDT thread ( UI thread ). Here is a very good explanation http://www.pushing-pixels.org/2007/12/06/unwritten-rule-of-working-with-swings-edt.html

Updating JTabbedPane when new tab is added

I'm working on a project, and have run into a little bit of a logic error, hopefully one of you can clear this up.
I'm building an application that will display a SQL database (among other things). Currently, the way I have things set up, I have a JTabbedPane inside a Container (BorderLayout.CENTER) not that this is really pertinent information.
Anywho, I would like to add a tab once the user has connected to a database (and eventually selected which 'table' to see. For now however, there is only one table to be displayed.
So, when the user hits 'Connect', ideally the connection will be successful, at which point in time a JTable is populated with the database information.
Once this table is initialized and ready to go, add it to a new JPanel, and add that panel to the JTabbedPane.
This is where the error comes in. I 'believe' my logic thus far is correct, and I don't get any compiler/runtime errors, the new tab just isn't shown (and if I click where it should be) nothing happens.
Below is some of my code, if anything needs clarified please don't hesitate to ask!
This is the Table_Builder Class code (I will clean it up once it is working properly!)
public class Table_Builder extends Framework
{
private DefaultTableModel updated_table_model;
private JTable updated_table;
private JScrollPane table;
public Table_Builder()
{
// no implemention needed
}
public Table_Builder(Vector rows, Vector columns)
{
updated_table_model = new DefaultTableModel(rows, columns);
updated_table = new JTable(updated_table_model);
updated_table.setCellSelectionEnabled(true);
updated_table.setFillsViewportHeight(false);
table = new JScrollPane(updated_table);
JPanel tab2 = new JPanel();
tab2.add(table);
tab2.setVisible(true);
center.add("Table Viewer", tab2);
// I'm thinking some sort of listener needs to be active, so it knows I'm adding a new
// tab, but I'm not sure how this actually works.
center.addPropertyChangeListener("foregroud", null);
center.repaint();
// center has already been added to container so i don't think that needs to be done again?
}
Framework
protected void center_panel()
{
JPanel tab1 = new JPanel();
tab1.add(//emitted);
center.setPreferredSize(new Dimension(1340, 950));
center.setBackground(new Color(90, 90, 90));
center.addTab("Tab1", tab1);
container.add(center, BorderLayout.CENTER);
}
Best Regards,
Mike
UPDATE:
Framework has these variables I am using to build the 'Frame'
Framework is a borderlayout (east, west, north, south, center)
protected JTabbedPane center // this is the center panel
protected Container container // this will house all panels to be added
As seen above, I am currently adding tabs by
1.) creating a new JPanel
2.) adding (whatever needs to be displayed) to the jpanel
3.) adding that jpanel to the JTabbedPane
this is done by
center.addTab("Tab name here", panel to be added);
The javadoc for this says
center.addTab("String title", Component component);
This works as intended, the problem I am encountering, is that this is done prior to server connection. After the user connects to the server, I would like to add a new tab, which is being done from Table_Builder, which inherits from Framework (which is why center and container are protected and not private).
Your code for adding a tab in the constructor is the following:
JPanel tab2 = new JPanel();
tab2.add(table);
tab2.setVisible(true);
center.add("Table Viewer", tab2);
// I'm thinking some sort of listener needs to be active, so it knows I'm adding a new
// tab, but I'm not sure how this actually works.
center.addPropertyChangeListener("foregroud", null);
center.repaint();
There are 2 errors and a lot of unnecessary lines. The errors are:
center.add("Table Viewer", tab2); is using the add function of the Container class. When you wanted to use center.addTab("Table Viewer", tab2);.
Just to clear up what #peeskillet was pointing out, there is not a "foregroud" property, nor a "forground" (as per your comment), but a "foreground" property.
Now what you need to do is just the following:
JPanel tab2 = buildTableViewerTab();
center.addTab("Table Viewer", tab2);
Where buildTableViewerTab() (returning a JPanel) is the code necessary to create the JPanel that you desire. Just create the component and add it to the tabbedPane properly.
To show how this code works here is a simple executable application demonstrating this functionality. Again, what #peeskillet was asking you in his second comment is to do this same example but in your own way and with your code demonstrating the errors you were encountering. Although doing this you probably would have found them.
import java.awt.BorderLayout;
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.JTabbedPane;
import javax.swing.SwingUtilities;
public class AddTabsExample
{
public static final void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new AddTabsExample();
}
});
}
public AddTabsExample()
{
JFrame frame = new JFrame("Tab adder frame");
final JTabbedPane tabbedPane = new JTabbedPane();
frame.add(tabbedPane);
JButton addButton = new JButton("Add tab");
addButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
JPanel newTabComponent = new JPanel();
int tabCount = tabbedPane.getTabCount();
newTabComponent.add(new JLabel("I'm tab " + tabCount));
tabbedPane.addTab("Tab " +tabCount, newTabComponent);
}
});
frame.add(addButton, BorderLayout.SOUTH);
addButton.doClick(); //add the first tab
frame.setSize(800, 300);//frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
Execution result:
call revalidate() on your center, then repaint.

Displaying an image in a JFrame

I am currently learning Java, and I am stuck with something at the moment.
I was looking for a way to add an image to my JFrame.
I found this on the internet:
ImageIcon image = new ImageIcon("path & name & extension");
JLabel imageLabel = new JLabel(image);
And after implementing it to my own code, it looks like this (this is only the relevant part):
class Game1 extends JFrame
{
public static Display f = new Display();
public Game1()
{
Game1.f.setSize(1000, 750);
Game1.f.setResizable(false);
Game1.f.setVisible(true);
Game1.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game1.f.setTitle("Online First Person Shooter");
ImageIcon image = new ImageIcon("C:\\Users\\Meneer\\Pictures\\image.png");
JLabel imageLabel = new JLabel(image);
add(imageLabel);
}
}
class Display extends JFrame
{
}
When running this code, it doesn't give me any errors, but it also doesn't show the picture. I saw some questions and people having the same problem, but their code was completely different from mine, they used other ways to display the image.
You don't need to use another JFrame instance inside the Game JFrame:
Calling setVisible(flag) from the constructor is not preferable. Rather initialize your JFrame from outside and put your setVisible(true) inside event dispatch thread to maintain Swing's GUI rendering rules using SwingUtilities.invokeLater(Runnable)
Do not give size hint by setSize(Dimension) of the JFrame. Rather use proper layout with your component, call pack() after adding all of your relevant component to the JFrame.
Try using JScrollPane with JLabel for a better user experience with image larger than the label's size can be.
All of the above description is made in the following example:
class Game1 extends JFrame
{
public Game1()
{
// setSize(1000, 750); <---- do not do it
// setResizable(false); <----- do not do it either, unless any good reason
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Online First Person Shooter");
ImageIcon image = new ImageIcon("C:\\Users\\Meneer\\Pictures\\image.png");
JLabel label = new JLabel(image);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
pack();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game1().setVisible(true);
}
});
}
}
do this after creating Jlabel
imageLabel.setBounds(10, 10, 400, 400);
imageLabel.setVisible(true);
also set the layout to JFrame
Game.f.setLayout(new FlowLayout);
You are adding the label to the wrong JFrame. Also, move the setVisible() to the end.
import javax.swing.*;
class Game1 extends JFrame
{
public static Display f = new Display();
public Game1()
{
// ....
Game1.f.add(imageLabel);
Game1.f.setVisible(true);
}
}
Also try to use image from resources, and not from hardcoded path from your PC
You can look in here, where sombody asked similar question about images in Jframe:
How to add an ImageIcon to a JFrame?
Your problem in next you add your JLabel to Game1 but you display another Frame(Display f). Change add(imageLabel); to Game1.f.add(imageLabel);.
Recommendations:
1)according to your problem: Game1 extends JFrame seems that Display is also a frame, use only one frame to display content.
2) use pack() method instead of setSize(1000, 750);
3)call setVisible(true); at the end of construction.
4)use LayoutManager to layout components.

JTabbed Pane creation in an external class

I'm playing around with some swing guis and am trying to create a basic program. This program is going to have a tabbed pane with a varying amount of tabs depending on the size of an array. (My end goal is to have users change the amount of items in the array, therefore changing the amount of tabs).
Each tab is going to have the exact same components, text area, table and a few buttons and labels. What I would like to do is instead of coding these tabs individually and rewriting my code over and over what I want to do is create a class to put all my components into.
I am however kind of stumped. This is my class for creating the tabs:
public class LocaleTab {
public LocaleTab(){
JPanel tab = new JPanel();
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(300, 300));
tab.add(label);
}
}
And here's my code that I'm trying to call with it:
LocaleTab tab1 = new LocaleTab();
JTabbedPane localesTabPane = new JTabbedPane();
localesTabPane.add(tab1);
I'm getting an error when I try and compile this. I'm thinking my methodology is probably completely wrong.
The method add(Component) in the type JTabbedPane is not applicable
for the arguments (LocaleTab)
One are that concerns me is when I try to use the data in the tables and text areas in each tab(event listeners is what I'll be using i think? I haven't gotten to that stage yet though!) how will I target the individual tabs components?
Change to:
public class LocaleTab extends JPanel {
public LocaleTab(){
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(300, 300));
add(label);
}
}
Probably you are looking for something close to this:
public class LocaleTab {
private JPanel tab;
public LocaleTab() {
tab = new JPanel();
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(300, 300));
tab.add(label);
}
public JPanel getTabPanel() {
return tab;
}
}
And use LocaleTab as shown below.
LocaleTab tab1 = new LocaleTab();
JTabbedPane localesTabPane = new JTabbedPane();
localesTabPane.add(tab1.getTabPanel());
Additionally to know about how JTabbedPane works please take a look here: How to Use Tabbed Panes

Categories