Aligning JButton - java

I have to align a button on my program to the exact middle, the current code I have runs it but displays the button as large as the program, I am wanting a center button that is a specific size, here is what I tried
/**
* Created by Timk9 on 11/04/2016.
*/
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame {
{
JFrame window = new JFrame("Test");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(true);
window.setSize(600, 600);
window.setVisible(true);
window.setLocationRelativeTo(null);
JPanel p = new JPanel(new GridBagLayout());
//Button does not appear until I resize the program?
JButton b1 = new JButton("Click here");
GridBagConstraints c = new GridBagConstraints();
p.add(b1);
window.add(p);
}
public static void main(String[] args) {
new Test();
}
}

JPanel p = new JPanel(new GridBagLayout());
You create a panel with a GridBagLayout which is a good layout manager to use to center the component.
p.add(b1);
But then you add the button to the panel without using any contraints.
The code should be:
p.add(b1, c);
//Button does not appear until I resize the program?
All components should be added to the frame BEFORE the frame is made visible. The setVisible(...) statement should be the last statement of the constructor.
Also could you point out which part is an instance initializer block, I thought I was using a constructor
See the FrameDemo example from the Swing tutorial on How to Make Frames for a better way to structure your code so you follow Swing conventions. Start with the working code and make the changes to add your panel containing the button, instead of using the JLabel. Note you no longer need to use the getContentPane() method, you can just add the panel directly to the frame.

It is the LayoutManager that defines how components are layed out where and how big. GridLayout which you are using e. g. divides the available space in equal grid fields and makes the components completely fill this space which is why your button is as big as your application. See here for more info about LayoutManagers: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Btw. your code is not compilable: new JButton("he"),JButton.ALIGN_CENTER)

Related

How to make a JButton that will create other buttons within a JPanel?

I am creating a user system to hold multiple details of multiple users. so i would like to create a button that would be able to create another button. when the second button is pressed a form will open for the user to fill. I have already created the form for the user to fill but i cannot manage to make the button to create more buttons to work. I have coded this but it does not show the button on the Jpanel.
I have created the following code:
private void mainButtonActionPerformed(java.awt.event.ActionEvent evt) {
JButton b=new JButton("Click Here");
b.setBounds(50,100,95,30);
jPanel3.add(b);
b.setVisible(true);
}
This doesn't seem to create a new button within jPanel3. Have I typed up the code incorrectly or is there an alternative correct way of doing this?
I would like 3 buttons in a row and then a new row of buttons.
Your code and question is missing too much information to be answered completely or well. About all I can say is
Always call jPanel3.revalidate() and jPanel3.repaint() on the container after adding or removing components from it as this tells the container's (here jPanel3) layout managers to re-layout all components and then re-draw them.
The container's layout manager is key for this to work well -- we have no idea what it is at the moment, and some layout managers will allow you to do this easily (e.g., FlowLayout, GridLayout) while others won't (e.g., GroupLayout).
There's no need for b.setVisible(true); since your newly created JComponent (JButton here) is already visible by default.
You appear to assume that it's using null layouts since you're calling setBounds(...), and this is a Bad Idea™. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
When asking such questions, try to create and post with the question a small but complete program that we can test and run, and that illustrates your problem, a minimal example program (please click on the link).
For example, my MCVE that shows how your code can work:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class AddButton extends JPanel {
private JPanel jPanel3 = new JPanel(); // panel to hold buttons
public AddButton() {
// create JButton that will add new buttons to jPanel3
JButton addMoreButtonsBtn = new JButton("Add More Buttons");
// give it an ActionListener
addMoreButtonsBtn.addActionListener(e -> {
final JButton newButton = new JButton("Click Here");
// when you click it, it removes itself (just for grins)
newButton.addActionListener(e2 -> {
jPanel3.remove(newButton);
// again revalidate and repaint
jPanel3.revalidate();
jPanel3.repaint();
});
// add to jPanel3, the "container"
jPanel3.add(newButton);
// revalidate and repaint the container
jPanel3.revalidate();
jPanel3.repaint();
});
// create a JPanel and put the add more buttons button to it
JPanel bottomPanel = new JPanel();
bottomPanel.add(addMoreButtonsBtn);
// give jPanel3 a layout that can handle new buttons
// a gridlayout with 1 column and any number of rows
jPanel3.setLayout(new GridLayout(0, 1));
// add it to the top of another JPanel that uses BorderLayout
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.add(jPanel3, BorderLayout.PAGE_START);
// and add that to a JScrollPane, so we can add many buttons and scroll
JScrollPane scrollPane = new JScrollPane(borderLayoutPanel);
// make the vert scrollbar always visible
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// force GUI to be larger
setPreferredSize(new Dimension(400, 200));
// give the main JPanel a BorderLayout
setLayout(new BorderLayout());
// and add scrollpane to center
add(scrollPane, BorderLayout.CENTER);
// add bottom panel to the bottom
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
AddButton mainPanel = new AddButton();
JFrame frame = new JFrame("AddButton");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

Adding JPanel to JFrame losing ability to organize components - Java

Description: I have been working on this small project in which I need to send a a specific JPanel from a class to the main JFrame based upon a parameter passed (1-4). In my main class I have a JFrame set up so I can visually check the panel being passed.
What doesn't work
Inside the "Accessor Class", I cannot seem to position the JComboBox in the middle of the Panel. Additionally, i'm not too sure I can do any kind of positioning. I implemented a button earlier with the exact same code (I replaced the JComboBox) and I couldn't resize the button either. HOWEVER... I can change the color of it.
GridBagLayout should center on default. Why is this being overridden? If you look at the picture/link provided, it shifts itself to the top center. I simply cannot move it.
Is this problem a result of the way I receive the JPanel from the class. Is there perhaps a better way I could call the panel.
Sorry for a lack of clarity. Struggling to comprehend some of the underlying concepts here in Java.
Any help is appreciated.
This is the main class
public static void main(String[] args) {
Accessor accessorOne = new Accessor(1); //Creates the Panel with param 1
JFrame frame = new JFrame("Testing");
frame.setLayout(new GridLayout(2,2));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.add(new JButton("Button 4"));
frame.add(accessorOne); //Adds the Panel to the last spot in the JFrame
frame.setSize(650, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
This is the "Accessor" class that defines the panel
public class Accessor extends JPanel{
JPanel panel = new JPanel();
public Accessor(int num){
if(num == 1){
panel.setLayout(new GridBagLayout());
String[] choice1 = {"Testing One", "Testing two" };
JComboBox choiceBoxOne = new JComboBox(choice1);
choiceBoxOne.setBackground(Color.red); //These changes are correctly reflected!
panel.add(choiceBoxOne);
choiceBoxOne.setLocation(300,300); //ERROR -> Setting this value changes nothing!
add(panel);
}
// Other num options
}
}
This is the photo of the Jframe
Problem is you are using panel within class Accessor(also a panel with default layout as FlowLayout). So instead of making another panel instance, you could have just use GridBagLayout to instance of Accessor and add controls directly to Accessor instead of new panel.
Again absolute positioning works with null layouts(not recommended).
Also don't forget to use GridBagConstraints along with GridBagLayout.

How to make a Jframe containing a Jpanel scrollable?

So I have this JFrame that contains a JPanel and in there I add JLabels with information I want but since I'll be adding labels all the time at some point the text is too long to appear so I want to add a scrollbar. Basically I want to make my JFrame with a JPanel in it scrollable. I have this code but my problem is that even though the scrollbar appears but it doesnt move and doesn't really work when the text is a lot, meaning the text still gets cut out and the scrollbar is there not moving. Does anyone know how to fix this?
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class Bar {
JFrame info = new JFrame("Information");
JLabel ballinf = new JLabel();
JPanel contentPane = new JPanel();
JScrollPane scrolling = new JScrollPane();
public Bar(){
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
scrolling = new JScrollPane(contentPane,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
info.add(scrolling);
info.setSize(750, 600);
info.setLocationByPlatform(true);
info.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
info.setVisible(true);
}
public void adding(int pos){
ballinf = new JLabel("Something ",JLabel.CENTER);//assume the text will be bigger here and have more info
ballinf.setSize(700, 30);
ballinf.setForeground(Color.green);
ballinf.setLocation(5, 5+pos);
contentPane.add(ballinf);
info.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
info.setVisible(true);
}
public static void main(String[] args){
Bar stats = new Bar();
stats.adding(0);
stats.adding(20);//this will be done in a for loop for more than 2 times so the text ends up to be a lot
}
}
contentPane.setLayout(null);
Don't use a null layout!!!
You need to use an appropriate layout manager. Read the section from the Swing tutorial on Layout Managers for more information and working examples. The layout manager will then determine the preferred size of the panel as you add components to the panel.
The scrollpane will then display the scrollbars when necessary.
If you dynamically add components to the panel (after the GUI is visible) then the code should be something like:
panel.add(...);
panel.revalidate();
panel.repaint();

How to reset or refresh Jframe with new values

I have a Jframe that the user enters new information through a Joptionpane, it is added to an array which is then appended and displayed to a contentpane.. the cycle then repeats till the user enters "STOP". Currently the program is outputting the new array under the old one. How would I clear away the old array in the content pane and only display the new values?
import java.awt.*;
import java.util.LinkedList;
import java.util.List;
public class Project1GUI {
static JFrame Frame;
static TextArea unsorted_words, sorted_words, linked_words;
public Project1GUI(String title){
//All this does is make an empty GUI FRAME.
Frame=new JFrame();//i made a new variable from the JFrame class
Frame.setSize(400,400);//Used the Variable from JFrame and used some of it functions. This function sets the hieght and width of the Frame
Frame.setLocation(200,200);//This sets where the Empty Frame should be
Frame.setTitle(title);//This puts a title up top of the Frame
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//places an x box that closes when clicked on
Frame.setVisible(true);//This activates the JFram when is set true.
Frame.setLayout(new GridLayout(1,2));//This sets the layout of the Frame and since i want a Grid i used a GirdLayout
//Functions and placed it inside the setlayout functions. to get 2 grids i places 1 meaning 1 row and 2 for 2 cols
unsorted_words=new TextArea(); //From the TextArea class i made three variables
sorted_words= new TextArea();
linked_words= new TextArea();
Container panel=new Container();
panel=Frame.getContentPane();
panel.add(unsorted_words);
panel.add(sorted_words);
panel.add(linked_words);
}
public void add_unsorted(String words){
unsorted_words.append(words+"\n");//add words to GUI
}
public void add_sorted(String words){
sorted_words.append(words+"\n");
}
public void add_linked(List<String> linked_words2){
linked_words.append(linked_words2+"\n");
}
}
For a more definitive answer, post an MCVE
Seeing as you haven't posted any code, I'm guessing you are using a JLabel or a JList or something of that sort to display the array. No matter which one you are doing, you need to tell the component to update it's content, it doesn't just do it itself. To do that, you need to call the components .setText() or similar method.
If you have a JLabel or JTextArea it could look like this.
labelOrTextArea.setText("New Text");
If you are using a JList you should update the lists Default List Model like this
dlm.addElement("New Text");
UPDATE
I see a couple things wrong with your code. First off JFrame Frame = new JFrame conventionally, variables should start with a lower case letter and they should not contain underscores '_'. You are also using AWT Components instead of Swing components. You should be using the likes of JTextArea, JPanel (Theres no JContainer), JLabel etc.
You are also never adding the panel to the frame.
frame.add(panel);
You should also not be adding stuff to the frame or panels after you set its visibility to true. So you should setup your frame like this
import javax.swing.*;
import java.awt.*;
import java.util.List;
public class Project1GUI
{
JTextArea unsorted_words, sorted_words, linked_words;
public Project1GUI()
{
JFrame frame = new JFrame("Title");
JPanel panel = new JPanel(new GridLayout(2, 1));
unsorted_words = new JTextArea();
sorted_words = new JTextArea();
linked_words = new JTextArea();
panel.add(unsorted_words);
panel.add(sorted_words);
panel.add(linked_words);
frame.add(panel);
frame.setSize(400,400);
frame.setLocation(200,200);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
You can then implement the methods you currently have and call them in an ActionListener or such.
Result:
On top of all of that, you should not rely on the use of static as it takes away from the main points of OOP.

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