Alright I'm relatively new to programming and it may be just something simple that I'm missing but the other threads related to this topic the poster didn't give adequate information relative to their issue for others to provide quality answers so I will give it a shot.
public BenchUI(JFrame j){
jf = j;
init();
add(mainPanel);
topPanelButtons();
selectedCustomer();
rentalOptions();
clientListBox();
}
At this point i can point out that everything works perfectly until I add the clientListBox() method. (below)
public void clientListBox(){
clientList = new JComboBox(moo);
clientList.setPreferredSize(new Dimension(460,30));
gbc.gridx = 0;
gbc.gridy = 0;
leftSide.add(clientList,gbc);
}
i can comment it out and get my whole GUI back working perfectly but without a JComboBox.
moo is String [] moo = {"Fish","Goat", "Monkey"};
a dummy string just for testing purposes and initialized at the start.
So any idea why my GUI completely disappears when I place in the clientList?
If anything else is necessary I'll be watching this thread and can provide additional information.
As a side note I keep getting warnings for "Raw Types" but it works without specifiying, could I potentially run into trouble by not specifying my JComboBox?
EDIT:
ok I believe I've duplicated whatever the issue is in this code
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
public class main {
public static void main(String[] args){
JFrame jf = new JFrame();
jf.setExtendedState(JFrame.MAXIMIZED_BOTH);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setResizable(false);
BenchUI bu = new BenchUI(jf);
jf.add(bu);
}
}
public class BenchUI extends JPanel{
JPanel one;
JFrame jf;
JComboBox<String> clientList;
String[] moo = {"Goat", "Fish", "Donkey"};
public BenchUI(JFrame j){
jf = j;
one = new JPanel(new GridBagLayout());
one.setBackground(Color.blue);
one.setPreferredSize(new Dimension(300,300));
clientList = new JComboBox<String>(moo);
one.add(clientList);
add(one);
}
}
with the clientList stuff commented out I get my silly little blue panel and once it is added I lose the blue panel and the combobox doesnt show up as well...betting on this is a facepalm issue at this point >.<
EDIT: to include the main class.
EDIT: took out the comment marks for the JComboBox constructor and implementer
Your posted sort of sscce-like (not a real SSCCE by the way since we can't run it) code doesn't add any such as the JComboBox to the JPanel and adds no components such as the current JPanel to the JFrame.
public class BenchUI extends JPanel{
JPanel one;
JFrame jf;
JComboBox<String> clientList;
String[] moo = {"Goat", "Fish", "Donkey"};
public BenchUI(JFrame j){
jf = j;
one = new JPanel(new GridBagLayout());
one.setBackground(Color.blue);
one.setPreferredSize(new Dimension(300,300));
//clientList = new JComboBox<String>(moo);
//one.add(clientList);
add(one);
}
}
and so it makes sense that none of the components will show up on any JFrame. You will want to read the Swing tutorials on how to add components to other components (or containers) and how to create and show a JFrame. Have a look at How to Use Swing Components.
Edit
Your latest code now does in fact add the BenchUI JPanel to the JFrame, but still you add no components to the BenchUI JPanel, and in fact you don't even construct your JComboBox but only create a JComboBox variable. Again, I strongly urge you to read the Swing tutorials which I've linked to above as well as the general Java tutorials.
Edit 2
Some general advice:
If you want to add a component to a GUI you must first create the component object. You are declaring your clientList JComboBox, but you never create the object.
Then you must add the component object to a container that eventually will be part of the hierarchy leading to a top level window such as a JFrame, JDialog, JApplet and such. You never add a clientList object to the GUI.
You should add your components to the top level window before calling pack() on the top level window -- which tells all the layout managers to lay out all the components they hold.
You should then call setVisible(true). One problem with your code (other than not creating important components and not adding them to the GUI!) is that you're calling setVisible(true) on your JFrame way too early before adding anything to the GUI.
Read the Swing tutorial, but especially the one on using layout managers and on adding components to a top level window.
Edit 3
OK, now you're creating your JComboBox, but you still are adding all components to your JFrame after setting it visible. Please re-check my 3rd and 4th bullets in the bullet list above.
Related
I am writing the back end code for my java project which is implementing a fitness logger. For some reason when I put the actionListener function to a button in my Border Layout then the button disappears.
I tried setting the function in different places in the constructor.
public class Buttons extends JFrame implements ActionListener {
JFrame frame = new JFrame("Menu");
JPanel MyPanel= new JPanel();
JButton b1= new JButton("Daily Logger");
JButton b2= new JButton("View Weekly Logs");
JButton b3= new JButton("Weight Calculator");
JButton b4= new JButton("BMI Calculator");
JButton b5= new JButton("Log Out");
public Buttons(){
MyPanel.setLayout(new BorderLayout());
MyPanel.add(b1, "North");
MyPanel.add(b2, "Center");
MyPanel.add(b3, "East");
MyPanel.add(b4, "West");
MyPanel.add(b5, "South");
b1.addActionListener(this);
add(b1);
frame.getContentPane().add(MyPanel, "North");
frame.setSize(500,115);
frame.setVisible(true);
}
public static void main(String[] args) {
new Buttons();
}
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if(command.equals("Daily Logger"))
myMethod();
}
public void myMethod() {
JOptionPane.showMessageDialog(this,"Onto the next step");
}
}
I expected the button to show up in the border layout when I add the actionListener function but it disappears. If the button did work as it should it should implement the myMethod() function. My main goal is to show my JTable that I created in another class to show up when the button is pressed.
add(b1);
Should be removed. The code has already added it via:
MyPanel.add(b1, "North");
A BorderLayout accommodates up to five components, each in a separate layout constraint. If a component is added twice, in different areas, it faces two problems:
A component can only appear in one place.
The component 'overwrites' the original component added to that area of the layout.
More general tips:
Please learn common Java nomenclature (naming conventions - e.g. EachWordUpperCaseClass, firstWordLowerCaseMethod(), firstWordLowerCaseAttribute unless it is an UPPER_CASE_CONSTANT) and use it consistently.
For better help sooner, add a minimal reproducible example or Short, Self Contained, Correct Example. Note: The posted code only needed appropriate import statements to be an MRE / SSCCE.
MyPanel.add(b3, "East"); re East
There are constants for this. E.G. BorderLayout.EAST. always use the constants for compile time checking.
But BorderLayout.LINE_END is sensitive to the locale. It will appear on the RHS for left to right languages, and the left for right to left languages.
All Swing & AWT GUIs should be created & updated on the EDT (Event Dispatch Thread).
The code both extends and keeps a reference to, JFrame. Keep the latter, ditch the former.
Be sure to add the java (language) and swing (GUI toolkit) tags to questions! The only reason I saw this was because I (extraordinarily) checked the question listing for the jframe tag! To the best of my recollection, it's the first time I've ever checked that tag's question listing. Even more ironic, it did not make the list of 5 tags I saw as being most relevant to this question.
frame.getContentPane().add(.. can be shortened to frame.add(.. since Java 1.5.
frame.setSize(500,115); should better be frame.pack();, since 500 x 115 is no better than a guess, and will be 'wrong' for different OS' (the size of the content pane will change due to different frame decorations per system).
By input elements I mean things like JSpinners and JComboxBoxes. My glasspane is passed a JPanel containing JSpinners, JComboBoxes and for the most part, JLabels. The glasspane has a MouseListener attached. The surprising thing is that mouseEntered is called upon the mouse cursor leaving the input elements and hovering over the other parts or empty space of the JPanel! Is this normal behaviour? How can I get the input elements to be considered part of the JPanel for Glasspane purposes?
Here is a screenshot of my UI with its input elements and jLabels.
Here is an example piece of Code:
import javax.swing.*;
public class DialogTest {
public DialogTest() {
JPanel dialogPanel = new JPanel();
SpinnerModel edgeModel = new SpinnerNumberModel(1, 1, 9, 1);
JSpinner edgeSpn = new JSpinner(edgeModel);
dialogPanel.add(edgeSpn);
JDialog initialDialog = new JDialog(new JFrame(), "Test", true);
initialDialog.setContentPane(dialogPanel);
initialDialog.pack();
glass = new GlassComponent(dialogPanel);
initialDialog.setGlassPane(glass);
glass.setOpaque(false);
glass.setVisible(true);
initialDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
initialDialog.setVisible(true);
}
}
public class GlassComponent implements MouseListener {
JPanel c;
public GlassComponent(JPanel c) {
this.c = c;
this.c.addMouseListener(this);
}
...
public mouseEntered(MouseEvent e) {
System.out.println("Entered JPanel");
}
}
By way of explanation, my goal is to eventually use the GlassPane to block input for those elements marked with the prohibition sign. However, given that the mouseListener assigned to the dialogPanel is seemingly generating new events upon leaving the input elements, I may have some difficulties achieving this.
You can forward mouse events to the underlying components, as shown in The Glass Pane demo's method, redispatchMouseEvent().
You appear to be using glasspane in a way that I feel it shouldn't be used.
As far as I know, a glasspane typically shouldn't be holding components at all but rather cover over the top-level window and then can act as a gate-keeper for the components that are below it, all held by the top level window's contentPane.
you can use GlassPane for overlay required Container or JComponent by #camickr, or my questions based on his code here or here,
another suggestion could be use JLayer (required Java7 for Java6 is there JXLayer)
I'm trying to close a frame yet open a new frame.
My application has page A, a JPanel with some controls and a specific button, and when the user clicks the button, I want page A to disappear and page B to appear (page B has controls that depend on the choices that are made by the user on page A).
This has been asked before, but there was no satisfactory answer. Inside the ActionListener implementation, namely public void ActionPerformed(ActionEvent e) from my jpanelForPageA class, I can comfortably write this.setVisible(false), but how can I set page B to a visible state?
You can do the removal of panel a and then the addition of panel b trick. Another is to use a CardLayout.
When you create your panels, you add them to a containing JPanel that you initialize with a CardLayout:
JPanel container = new JPanel(new CardLayout());
containter.add(getPanelA(), "PANEL_A");
containter.add(getPanelB(), "PANEL_B");
Then, in your actionPerformed, when you want to show panelB, you do this:
CardLayout cl = (CardLayout) container.getLayout();
cl.show("PANEL_B");
Take a look at this tutorial for some more ideas.
For some reason, I can never to get setVisible() to work for me to do what you're describing. Instead, I do this:
frame.remove(panelA);
frame.add(panelB);
"frame" is just the JFrame you want to put the panels in. Try this if the setVisible() method doesn't work :)
To your original question, all you have to do is (like aioobe said):
panelB.setVisible(true);
((btw, posting some of your code would help me figure out what you're trying to ask))
And this is just a guess as to what you're trying to do -- I'm guessing your JPanels are in different classes. Then, you'll need to do this:
class pages extends JFrame implements ActionListener
{
public pages()
{
panelA a = new panelA(this)
}
changeToA(panelB b)
{
remove(panelB);
add(new panelA(this));
}
changeToB(panelA a)
{
remove(panelA);
add(new panelB(this));
}
}
class panelA extends JPanel implements ActionListener
{
pages p;
public panelA(pages p)
{
this.p = p
}
// all that actionlistener code stuff
p.changeToB(this);
}
class panelB extends JPanel implements ActionListener
{
pages p;
public panelB(pages p)
{
this.p = p
}
// all that actionlistener code stuff
p.changeToA(this);
}
You pass the pages class to the panels so the panels can tell the pages class to remove themselves.
((I don't know if there is an easier way, but this is what I do all the time))
I hope I helped :)
You have to remove Panel A from the frame, add Panel B to the frame, and call invalidate on the frame (or containing panel). At least in Swing, I'm not sure about AWT, there you might need repaint or revalidate instead of invalidate.
You could also just create a whole new JFrame and dispose the one containing panel A.
This code, when run, will make a window but not at the specified dimensions. What is wrong with it?
import javax.swing.*;
import java.awt.*;
public class Windowing {
void JFrame(){
JFrame frames = new JFrame("Total recall");
frames.setSize(1000,8000);
frames.setVisible(true);
frames.pack();
//Buttons push = new Buttons();
//((Buttons) push).buttons();
JTextField wager = new JTextField(1);
wager.setSize(100,200);
wager.setVisible(true);
wager.setLocation(100, 200);
frames.add(wager);
//frames.add(push);
}
}
You could remove the call to frames.pack(); it overrides the previously set frame size.
However, what you really want to do is remove the frames.setSize(1000,8000) and move frames.pack() down to the bottom of the method; that will ensure that the frame is big enough to display its contents but not too big to fit on the screen.
If you call pack before adding anything to the frame (like you are doing now), it will make the window extremely small; it's probably appearing near the upper left of your screen, but you won't notice it unless you know where to look.
It looks like you have a number of "opportunity areas" here.
To start, it seems like you set frame size to 1000x8000 because you didn't see any change right?
Secondly you call setVisible on the textField because you didn't see that either.
And finally you're setting the size of the textfield ( I guess because you're seeing it take the whole frame )
The problem here is that you have to invoke pack and setVisible at the end of the construction. Also, you have to learn how to use layout managers and frames.
Swing, is very powerful, but it is a bit hard to grasp at the beginning.
These two links will be helpful:
How to make frames
Using Layout Managers
I've changed your code and the result looks like this:
Here's the modified source code.
import javax.swing.*;
import java.awt.*;
public class Windowing {
public static void main( String [] args ) {
Windowing windowing = new Windowing();
windowing.showFrame();
}
void showFrame(){
JFrame frame = new JFrame("Total recall");
JButton push = new JButton("Push");
JTextField wager = new JTextField(15);
// Panels do have "FlowLayout"
JPanel panel = new JPanel();
panel.add(wager);
panel.add(push);
frame.add( panel );
frame.pack();
frame.setVisible(true);
}
}
Try to use setPreferredSize(Dimension) instead.
I am trying something very basic:
I have a list of 5 buttons. They are in a FlowLayout and the general idea should be that once I click one it should disappear and the others should reorder themselves accordingly.
Now, if I call setVisible(false) the button becomes invisible, but it still occupies it's space in the Layoutmanager.
Is there any way to keep the Button in the JPanel while hiding it so it doesn't get picked up by Layout?
Update:: Thanks for all the answers, the problem with removing the buttons is that the order is important. The problem I was trying to solve was a find as you type szenario where a very long list of buttons gets filtered down to only the ones matching the characters entered so users can easily click them. Since users can delete characters from the search field ordering is important and buttons have to pop back in once they match again.
Works fine for me.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FlowLayoutInvisible extends JFrame
implements ActionListener
{
JPanel north;
int i;
public FlowLayoutInvisible()
{
north = new JPanel();
for (int i = 0; i < 5; i++)
{
JButton button = new JButton("North - " + i);
button.addActionListener(this);
north.add(button);
}
getContentPane().add(north, BorderLayout.NORTH);
}
public void actionPerformed(ActionEvent e)
{
Component c = (Component)e.getSource();
c.setVisible(false);
((JPanel)c.getParent()).revalidate();
}
public static void main(String[] args)
{
FlowLayoutInvisible frame = new FlowLayoutInvisible();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
If you need more help post your SSCCE.
Update: I don't know if the revalidate() is required. I seemed to have a problem once but now I can't duplicate the problem.
Just remove it:
panel.remove( button );
What's wrong with this option?
Layout managers are thought precisely to avoid having the "user" to make tricks in order to have each component it the right place ( although it seems to provoke the opposite effect )
Removing the button from the panel will have the effect of laying out again all the remaining components. That's why it's name is "Layout manager" it manages to layout the components for you.
I see two possibilities:
Write your own layout manager that listens for changes to its children's visible property - shouldn't be too hard, you can probably subclass FlowLayout to do it.
actually remove the clicked-button from the panel and, if necessary, re-add it later.
You could override each button's getPreferredSize() methods (and possibly getMinimumSize() as well to return 0,0 when the component is invisible; and you need to call, I think, invalidate() (or revalidate or validate, I can never keep them straight) on the container.