In my code, My okButton is in bad appear, so large and long, How fix this problem?
public class d7Table extends JFrame {
public JTable table;
public JButton okButton;
public d7Table() {
table = new JTable(myTableModel(res));
okButton = new JButton("Ok");
add(new JScrollPane(table), BorderLayout.CENTER);
add(okButton, BorderLayout.PAGE_END);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800, 600);
this.setLocation(300, 60);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new d7Table();
}
});
}
}
I remove Irrelevant codes.
You've added the button to the SOUTH position of a BorderLayout. This is the default behaviour of BorderLayout.
To fix it, create another JPanel, add your button to it, then add the panel to the SOUTH position instead
Take a look at
A visual guide to layouts
Using Layout Managers
The approach mentioned above is commonly known as compound layouts, as you use a series of containers with different layout managers to achieve the desired effect.
JPanel buttonPane = new JPanel(); // FlowLayout by default
JButton okayButton = new JButton("Ok");
buttonPanel.add(okayButton);
add(okayButton, BorderLayout.SOUTH);
Because the default layout of JFrame is BorderLayout, and PAGE_END means the bottom of the frame horizontally like this:
You have to change the layout of the frame, but don't do that, just create a panel, and add the components to it then add the panel to the container.
JPanel p = new JPanel();
p.add(okButton);
add(p,BorderLayout.PAGE_END);
Here some links may help you understand more about layout managers that usually used:
How To Use BorderLayout
How To Use FlowLayout
And MigLayout which I prefer to use it as it's very flexible layout manager, try it it's amazing.
import java.awt.*;
import javax.swing.*;
public class TableAndButton extends JFrame {
public JTable table;
public JButton okButton;
public TableAndButton() {
table = new JTable();
okButton = new JButton("Ok");
add(new JScrollPane(table), BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.add(okButton);
add(bottomPanel, BorderLayout.PAGE_END);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//this.setSize(800, 600); better to call pack()
this.pack();
//this.setLocation(300, 60); better to..
this.setLocationByPlatform(true);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TableAndButton();
}
});
}
}
Related
In my software i have a JPanel containing some JComponent. The JPanel use a FlowLayout with a certain Hgap to separate these components.
I'm trying to have this kind of design, but the first component should be layed out on left, without any Hgap. Like This:
here is the code you can use to generate the example:
public class FlowLayoutExample {
public static void main(String [] a) {
final JFrame frame = new JFrame();
frame.setSize(new Dimension(500, 80));
frame.setMinimumSize(new Dimension(350, 80));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(initJPanel());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
}
private static JPanel initJPanel() {
JPanel panel = new JPanel();
FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT);
flowLayout.setHgap(25);
panel.setLayout(flowLayout);
panel.setBackground(Color.LIGHT_GRAY);
panel.add(initLabel());
panel.add(initLabel());
panel.add(initLabel());
panel.add(initLabel());
return panel;
}
private static Component initLabel() {
return new JLabel("MyLabel");
}
}
Thanks for any suggestion you'll leave !
You can use an EmptyBorder to fake it out:
panel.setBorder( new EmptyBorder(0, -25, 0, 0) );
Basically the border inset and layout gap are added together.
I want to write a simple Java program, which consists of a JFrame that integrates a JScrollPane. Just it does not work the way I do it.
What is the issue of the my approach ?
public class TestView {
JFrame frame;
JScrollPane scrollPane;
public TestView(){
frame = new JFrame();
scrollPane = new JScrollPane();
scrollPane.add(new JLabel("Klick me"));
scrollPane.setMinimumSize(new Dimension(200,200));
frame = new JFrame();
frame.getContentPane().add(scrollPane);
frame.setSize(200,200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void createAndShowGui(){
TestView tv = new TestView();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGui();
}
});
If the issue is that you do not see your label in the scrollpane, you might need to use
scrollpane.setViewportView(new JLabel("Klick me"));
instead of
scrollPane.add(new JLabel("Klick me"));
Additionally, I suggest you create a JPanel, give it a layout, and place your label there, instead of passing the label to the scrollpane. Then set this panel as the viewport.
Please see
Difference between JscrollPane.setviewportview vs JscrollPane.add
use for example:
final JPanel myPanel = new JPanel();
myPanel.setPreferredSize(new Dimension(50, 50));
final JScrollPane scrollPane = new JScrollPane(myPanel);
setMinimumSize will be ignored.
Components are not displayed in my JFrame using Swing.
Actually my aim is:
Add Frame
In the frame add panel
Panel cantains 3 buttons
But it didn't show.
Here is my code
public class Panels
{
JFrame frame;
JPanel panel;
private JButton addButton;
private JButton modifyButton;
private JButton deleteButton;
Panels()
{
initGUI();
launchFrame();
}
public void initGUI()
{
frame = new JFrame();
panel = new JPanel();
addButton = new JButton("Add");
modifyButton = new JButton("Modify");
deleteButton = new JButton("Delete");
}
public void launchFrame()
{
addButton.setBounds(130,50,225,25);
addButton.setBounds(150,50,225,25);
addButton.setBounds(170,50,225,25);
addButton.setBounds(190,50,225,25);
panel.add(addButton);
panel.add(modifyButton);
panel.add(deleteButton);
panel.setLayout(null);
panel.setBackground(Color.RED);
frame.add(panel);
frame.setTitle("My Frame with Panel");
frame.setSize(600,400);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here is main for calling Panels class
When run on main function Frame is shown without controllers (ie 3 buttons not shown)
public class Main
{
public static void main(String[] args)
{
Panels obj_panel=new Panels();
}
}
This is the main problem
frame.setLayout(null);
When you set the layout to null, that means that all of its components must have boundaries set. You try to add the panel, without any boundaries. You only set the boundaries for the buttons in the panel. If you remove the above line, it works.
Other Issues I'd really take a look at:
Don't use null layouts at all. Instead make use of layout managers, and let them handle the sizing and positioning for you. This results in a a much more manageable and flexible UI. Please take some time to learn the different layout managers. Start at Laying out Components Within a Container
All Swing apps should run on a special thread known as the Event Dispatch Thread (EDT). Please take some time to read Initial Threads to learn how you can accomplish this.
Here is a refactor (fixing the "Other issues") with no null layout, just using layout managers, margins, and borders, and the code in the main shows how to run the program on the Event Dispatch Thread
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
Panels obj_panel = new Panels();
}
});
}
}
class Panels {
private JFrame frame;
private JPanel panel;
private JButton addButton;
private JButton modifyButton;
private JButton deleteButton;
Panels() {
initGUI();
launchFrame();
}
private void initGUI() {
frame = new JFrame(); // default layout manager is BorderLayout
panel = new JPanel(); // default layout manager is FlowLayout
addButton = new JButton("Add");
modifyButton = new JButton("Modify");
deleteButton = new JButton("Delete");
}
private void launchFrame() {
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
buttonPanel.setBackground(Color.RED);
buttonPanel.add(addButton);
buttonPanel.add(modifyButton);
// add margin to left and right of delete button
// other buttons will follow suit because of GridLayout
deleteButton.setMargin(new Insets(0, 50, 0, 50));
buttonPanel.add(deleteButton);
// create some space at the top for the buttonPanel
buttonPanel.setBorder(new EmptyBorder(20, 0, 0, 0));
panel.add(buttonPanel);
panel.setBackground(Color.RED);
frame.add(panel);
frame.setTitle("My Frame with Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
As you see the code, I would like to implement the 2nd tab with a text area, scrolling, and a button down there. This (JScrollPane scr = new JScrollPane(secondTab(panel2));) code was in the function, private static JTextArea secondTab(JPanel panel) before but I took it out of the function and put that back to MainFrame. Because the scroll and text area didn't show up. Now that I moved the code to mainframe the tex tarea and scroll are visible, but I'm struggling with making the button showing up in the 2nd tab. Do you guys have any idea?
public MainFrame(String username)
{
JTabbedPane tab = new JTabbedPane();
mainFrame.add(tab, BorderLayout.CENTER);
JPanel panel1 = new JPanel();
firstTab(panel1);
tab.add("babababa", panel1);
JPanel panel2 = new JPanel();
JScrollPane scr = new JScrollPane(secondTab(panel2));
JButton saveButton = new JButton("Save");
panel2.add(saveButton);
saveButton.setBounds(190, 280, 80, 40);
tab.add("hahaha", panel2.add(scr));
mainFrame.setBounds(200,200,500,400);
mainFrame.setVisible(true);
}
private static JTextArea secondTab(JPanel panel) {
panel.setLayout(null);
final JTextArea nameTextArea=new JTextArea();
nameTextArea.setBounds(10,10,440,270);
nameTextArea.setLineWrap(true);
return nameTextArea;
}
}
You should avoid use of null layout as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain. Not only that, JScrollPanes do not work well when the viewport view (the component that you display inside of the JScrollPane) uses null layout. Not only that, if you set the bounds or even the preferred size of a JTextArea, it will not expand inside the JScrollPane and you won't see scrollbars.
Solution:
Avoid using null layouts like the plague.
Learn and use the layout managers: The Swing Layout Manager Tutorials
Never set a JTextArea's size or preferredSize. Instead consider setting its columns and rows.
For example:
import java.awt.BorderLayout;
import javax.swing.*;
public class MainFrame2 extends JPanel {
private JTabbedPane tabbedPane = new JTabbedPane();
private JTextArea textArea = new JTextArea(20, 40);
public MainFrame2() {
tabbedPane.add("Bahahahaha", new JPanel());
tabbedPane.add("TextArea Info", createTextAreaPane());
setLayout(new BorderLayout());
add(tabbedPane, BorderLayout.CENTER);
}
private JComponent createTextAreaPane() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton("Save"));
JPanel textAreaPane = new JPanel(new BorderLayout());
textAreaPane.add(new JScrollPane(textArea), BorderLayout.CENTER);
textAreaPane.add(btnPanel, BorderLayout.SOUTH);
return textAreaPane;
}
private static void createAndShowGui() {
MainFrame2 mainPanel = new MainFrame2();
JFrame frame = new JFrame("Main Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
It's better to build each tab panel in each method.
private JPanel buildFirstTab() {
// create new panel
// add components to the panel
// return the panel
}
private JPanel buildSecondTab() {
// create new panel
// create JScrollPane
// create JTextArea
// add text area to scrollpane by calling scrollpane.setViewPort method
// add scrollpane to the panel
// create button
// add button to the panel
// return the panel
}
public MainFrame(String username) {
JTabbedPane tab = new JTabbedPane();
mainFrame.add(tab, BorderLayout.CENTER);
tab.add("1st tab", buildFirstTab());
tab.add("2nd tab", buildSecondTab());
mainFrame.setBounds(200,200,500,400);
mainFrame.setVisible(true);
}
Adding to the previous answer, try to use the simple layout like BoxLayout (adds components on top of each other), or FlowLayout (adds components next to previous component), then learn more complex layout like GridBagLayout (so far, this is the best layout for me, most of the time).
I am working on the editor. I am using Java swing for it. I have embedded a JTextArea with JScrollPane. i want to position the jtextarea of particular size at the middle of JScrollPane. To do this I used setLocation function. But this is not working?
public class ScrollPaneTest extends JFrame {
private Container myCP;
private JTextArea resultsTA;
private JScrollPane scrollPane;
private JPanel jpanel;
public ScrollPaneTest() {
resultsTA = new JTextArea(50,50);
resultsTA.setLocation(100,100);
jpanel=new JPanel(new BorderLayout());
jpanel.add(resultsTA,BorderLayout.CENTER);
scrollPane = new JScrollPane(jpanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(800, 800));
scrollPane.setBounds(0, 0, 800, 800);
setSize(800, 800);
setLocation(0, 0);
myCP = this.getContentPane();
myCP.setLayout(new BorderLayout());
myCP.add(scrollPane);
setVisible(true);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new ScrollPaneTest();
}
}
You simply have to add the JTextArea to the JScrollPane, and add it to the CENTER of the JPanel having BorderLayout.
Don't use AbsolutePositioning. Add a proper LayoutManager, and let LayoutManager do the rest for positioning and sizing your components on the screen.
In order to use the setBounds(...) method you have to use a null Layout for your component, which is not worth using, provided the perspective, as mentioned in the first paragraph of the AbsolutePositioning. Though in the code example provided by you, you are doing both the thingies together i.e. using Layout and using AbsolutePositioning, which is wrong in every way. My advice STOP DOING IT :-)
In the example provided the ROWS and COLUMNS provided by you are sufficient to size the JTextArea by the Layout concern.
Code Example :
import java.awt.*;
import javax.swing.*;
public class Example
{
private JTextArea tarea;
private void displayGUI()
{
JFrame frame = new JFrame("JScrollPane Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JScrollPane textScroller = new JScrollPane();
tarea = new JTextArea(30, 30);
textScroller.setViewportView(tarea);
contentPane.add(textScroller);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new Example().displayGUI();
}
});
}
}