I am developing a GUI form in java. In that I am adding two panels in main frame which has FlowLayout. But now I want to change the size of panels and I tried changing using setsize(), and I can see no difference.
Here is my code:
public class Main_window extends JFrame implements ActionListener {
JFrame MainFrm = new JFrame("MCQ Generator");
JPanel LeftPanel = new JPanel();
JPanel RightPanel = new JPanel();
JButton BrowseButton = new JButton("Browse/Open");
TextArea ta1 = new TextArea();
TextArea ta2 = new TextArea();
JButton ClearWindow = new JButton("Clear Window");
JButton generateButton = new JButton("Generate MCQs");
String fname;
Main_window() {
MainFrm.setLayout(new FlowLayout(FlowLayout.LEFT));
MainFrm.setSize(1050, 400);
MainFrm.add(LeftPanel, FlowLayout.LEFT);
MainFrm.add(RightPanel);
LeftPanel.setLayout(new BorderLayout(30, 30));
//LeftPanel.setSize(10, 10);
//RightPanel.setSize(10, 10);
RightPanel.setLayout(new BorderLayout(40, 40));
LeftPanel.setOpaque(true);
LeftPanel.setBackground(Color.LIGHT_GRAY);
LeftPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
RightPanel.setOpaque(true);
RightPanel.setBackground(Color.LIGHT_GRAY);
RightPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel InnerPanel = new JPanel();
InnerPanel.setLayout(new FlowLayout());
InnerPanel.setBackground(Color.LIGHT_GRAY);
InnerPanel.add(new JLabel("Choose File: "));
LeftPanel.add(InnerPanel, BorderLayout.NORTH);
LeftPanel.add(ta1, BorderLayout.CENTER);
RightPanel.add(new JLabel("Questions Generated:"), BorderLayout.NORTH);
RightPanel.add(ta2, BorderLayout.CENTER);
//ta1.setSize(10, 100);
//ta2.setSize(10, 100);
BrowseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Text Documents(*.txt)", "txt");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(LeftPanel);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You choose to open this file: " + chooser.getCurrentDirectory() + "\\" + chooser.getSelectedFile().getName());
fname = new String(chooser.getCurrentDirectory() + "\\" + chooser.getSelectedFile().getName());
try {
Jdbc_conn.truncateInputTable(ta1);
displayInput(fname);
//Jdbc_conn.truncateInputTable(ta1);
Give_input.getInput(fname);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
InnerPanel.add(BrowseButton);
LeftPanel.add(generateButton, BorderLayout.SOUTH);
generateButton.addActionListener(this);
RightPanel.add(ClearWindow, BorderLayout.SOUTH);
ClearWindow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
try {
Jdbc_conn.truncateMcqAndNew_nountab(ta2);
} catch (Exception e) {
e.printStackTrace();
}
}
});
MainFrm.setVisible(true);
MainFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
Usually, when setSize() doesn't work, try with setPreferredSize().
In this case, as the Oracle tutorial says: "The FlowLayout class puts components in a row, sized at their preferred size. If the horizontal space in the container is too small to put all the components in one row, the FlowLayout class uses multiple rows. If the container is wider than necessary for a row of components, the row is, by default, centered horizontally within the container. To specify that the row is to aligned either to the left or right, use a FlowLayout constructor that takes an alignment argument. Another constructor of the FlowLayout class specifies how much vertical or horizontal padding is put around the components."
First, take a look at Laying Out Components Within a Container for information about the layout API.
You should never (okay, very rarely) need to call setSize on a component directly. Any component under the management of a layout manager will be sized to meet the requirements of the layout manager, so generally speaking, call setSize is a pointless exercise
You might be able effect the size of a component by using an EmptyBorder, but this is just adding internal padding to the component, which might not be desirable.
Another choice is to use a different layout manager which gives you more control, something like MigLayout or GridBagLayout, but this will increase the general complexity of the code.
The other choice would be to override the getPreferredSize method of the components you want to size and return the values you want to use. Be warned though, this is not to be done lightly or without a lot of consideration to "why" you want to change the default size. The main reason is, different platforms can change the amount of space any component might need in order to be laid out correctly.
Related
I am trying to get a JInternalFrame to appear on my screen when a button is pressed, a pop up effect basically. However when the button is pressed the JInternalFrame does not appear on the screen. Also when I resize the screen all the elements expand with it, I am wondering if there is a way to get a pop up window to appear on the screen and keep the layout manager I have now still in place so that when the window is resized the elements are also resized with it
public class testing2 implements ActionListener {
JButton buttonAppear = new JButton();
JLayeredPane LayeredPane = new JLayeredPane();
public static void main(String[] args) {
new testing2();
}
public testing2() {
LayeredPane = new JLayeredPane();
BorderLayout borderlayoutpane = new BorderLayout();
LayeredPane.setLayout(borderlayoutpane);
JPanel mainPanel = new JPanel();
BorderLayout borderlayout = new BorderLayout();
mainPanel.setLayout(borderlayout);
JButton button = new JButton("Button");
mainPanel.add(button, "Center");
buttonAppear = new JButton("Panel Appear");
buttonAppear.addActionListener(this);
mainPanel.add(buttonAppear, "South");
LayeredPane.add(mainPanel, 2);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(LayeredPane);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == buttonAppear)
{
JInternalFrame inFrame = new JInternalFrame("Internal Frame", true, true, true, true);
inFrame.setBounds(10, 10, 200, 200);
inFrame.setVisible(true);
LayeredPane.add(inFrame, 1);
}
}
}
a pop up effect basically.
Then use a JDialog. A JInternalFrame was designed to work with a JDesktopPane.
mainPanel.add(button, "Center");
Don't use hardcode strings for the constraint. Use the field provided by the API:
mainPanel.add(button, BorderLayout.CENTER);
Also, follow Java naming conventions. Variable names should NOT start with an upper case character. Be consistent.
Don't know if it will make a difference but components with a higher layer number are painted on top of components with a lower index. So I would guess the panel (which is opaque) would just paint over top of the internal frame. Read the section from the Swing tutorial on How to Use Layered Panes. Also read the section on How to Use Root Panes to find the special variable for "popups" on a layered pane.
Currently working on a project and I need to add a panel I've made to a scrollpane or a table dynamically. The scrollpane should start out empty and add the panels.
The GuiConstructor is where i make the window.
My problem is that if I don't comment out the setSize in the GuiConstructor, the window starts out very small.
Secondly, when i press the add button, it doesn't add the panels.
public GuiConstructor(){
super(APPLICATION_NAME);
setLayout(new BorderLayout());
LoopControlWindow loopwin = new LoopControlWindow(connect);
add(loopwin , BorderLayout.NORTH);
pack();
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
//this.setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class LoopControlWindow extends JPanel {
IConnector connect;
public LoopControlWindow(IConnector connect) {
super(new BorderLayout());
this.connect = connect;
initPane();
}
private void initPane() {
JPanel panel = new JPanel(new GridLayout(3,1));
FolderSearchComp fsc = new FolderSearchComp(connect);
JScrollPane scrollPane = new JScrollPane();
JButton button = new JButton("Add");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel.add(new FolderSearchComp(connect));
scrollPane.getViewport().setView(panel);
}
});
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setViewportBorder(new LineBorder(Color.BLACK));
add(scrollPane, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
}
This is typical of this style of GUI app. You need to tell the layout manager how big to make the Window initialy without using setSize(). The way to do this is to override getPreferredSize() to return a default size. In your case:
public LoopControlWindow extends JPanel {
private Dimension size;
public LoopControlWindow() {
Preferences prefs = Preferences.userNodeForPackge("your.java.package");
size = new Dimension(prefs.getInt("width", 800), prefs.getInt("height", 600));
}
public Dimension getPreferredSize() {
return size;
}
}
By doing it this way you can store the user preferences for the window dimensions but also provide sensible defaults to start.
You should also make sure that this JPanel is your main panel and is added to the JFrame at BorderLayout.CENTER to ensure that your window gets drawn properly. All other panels should be somewhere inside this one.
Once you have this set up calling pack() will work correctly.
For your first problem, you need to specify a size for the initial JFrame(). One way is to call setSize as you are doing. Another is to override getPreferredSize() to return the default size. And one other option is to find the size of the user's monitor and set the JFrame to be a percentage of that size. That way you can ensure your window always fits on your user's screen.
int height = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration().
getBounds().height;
height = (int) (height * .85);
int width = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration().
getBounds().width;
width = (int) (width * .85);
frame.setSize(width, height);
Second, you need to call revalidate() and repaint() anytime you add or remove from a layout in order to see the changes.
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel.add(new FolderSearchComp(connect));
scrollPane.getViewport().setView(panel);
revalidate();
repaint();
}
});
One note on border layout. The components in it will not resize with your JFrame. Whatever component that is placed in BorderLayout.CENTER will, however. That component will grow to fill all extra space as the JFrame grows. It will also be the component that shrinks when the JFrame windows gets smaller.
Here is my code. The button is the same size as the FlowLayout. How can I make the button smaller?
public class javalearning extends JFrame{{
FlowLayout f = new FlowLayout();
this.setSize(600,600);
JFrame j = new JFrame();
this.setTitle("this is a tittle");
JButton button = new JButton();
button.setText("Button");
this.add(button);
button.setBounds(10, 10, 10, 10);
this.setVisible(true);
}
}
I think you forget to setLayout, it works fine when I do. Don't use setBounds and put it in a javalearning constructor and I also suggest you setDefaultCloseOperation like
public javalearning() {
FlowLayout f = new FlowLayout();
this.setLayout(f);
this.setSize(600, 600);
this.setTitle("this is a tittle");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton();
button.setText("Button");
this.add(button);
// button.setBounds(10, 10, 10, 10);
this.setVisible(true);
}
public static void main(String[] args) {
javalearning m = new javalearning();
}
Finally, by convention, Java class names start with a capital letter and are camel case. Something like JavaLearning would follow that convention.
You never set the layout manager (FlowLayout) to the frame, therefore the JFrame is still using it's default layout manager of BorderLayout...
Try using something more like...
FlowLayout f = new FlowLayout();
setLayout(f);
this.setTitle("this is a tittle");
JButton button = new JButton();
button.setText("Button");
this.add(button);
this.pack();
this.setVisible(true);
instead...
Take a closer look at Laying Out Components Within a Container for more details
FlowLayout will lay out Components left-to-right (or right-to-left) wrapping them if required. If you wish to explicitly set the size of each JButton you should use setPreferredSize rather than setSize or setBounds as layout managers typically make use of the minimum, preferred and maximum sizes when performing a layout.
button.setBounds(x, y, height, width);
you can give height and width less than 10!
also you can use GridLayout for smaller buttons in one button with for loop
I am trying to get a JInternalFrame to appear on my screen when a button is pressed, a pop up effect basically. However when the button is pressed the JInternalFrame does not appear on the screen. Also when I resize the screen all the elements expand with it, I am wondering if there is a way to get a pop up window to appear on the screen and keep the layout manager I have now still in place so that when the window is resized the elements are also resized with it
public class testing2 implements ActionListener {
JButton buttonAppear = new JButton();
JLayeredPane LayeredPane = new JLayeredPane();
public static void main(String[] args) {
new testing2();
}
public testing2() {
LayeredPane = new JLayeredPane();
BorderLayout borderlayoutpane = new BorderLayout();
LayeredPane.setLayout(borderlayoutpane);
JPanel mainPanel = new JPanel();
BorderLayout borderlayout = new BorderLayout();
mainPanel.setLayout(borderlayout);
JButton button = new JButton("Button");
mainPanel.add(button, "Center");
buttonAppear = new JButton("Panel Appear");
buttonAppear.addActionListener(this);
mainPanel.add(buttonAppear, "South");
LayeredPane.add(mainPanel, 2);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(LayeredPane);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == buttonAppear)
{
JInternalFrame inFrame = new JInternalFrame("Internal Frame", true, true, true, true);
inFrame.setBounds(10, 10, 200, 200);
inFrame.setVisible(true);
LayeredPane.add(inFrame, 1);
}
}
}
a pop up effect basically.
Then use a JDialog. A JInternalFrame was designed to work with a JDesktopPane.
mainPanel.add(button, "Center");
Don't use hardcode strings for the constraint. Use the field provided by the API:
mainPanel.add(button, BorderLayout.CENTER);
Also, follow Java naming conventions. Variable names should NOT start with an upper case character. Be consistent.
Don't know if it will make a difference but components with a higher layer number are painted on top of components with a lower index. So I would guess the panel (which is opaque) would just paint over top of the internal frame. Read the section from the Swing tutorial on How to Use Layered Panes. Also read the section on How to Use Root Panes to find the special variable for "popups" on a layered pane.
I want to add a scroll bar into my text area and I know the simple code for adding scroll bar but when I put the code for scroll bar the whole text area disappears!
What is the problem?
Here is my code:
private JFrame frame;
private JTextArea textarea;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SmsForm window = new SmsForm();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SmsForm() {
initialize();
}
private void initialize() {
frame = new JFrame("???");
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel groupBoxEncryption = new JPanel();
final JTextArea textarea=new JTextArea();
textarea.setBounds(50, 100, 300, 100);
frame.getContentPane().add(textarea);
textarea.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
JScrollPane scrollPanePlain = new JScrollPane(textarea);
groupBoxEncryption.add(scrollPanePlain);
scrollPanePlain.setBounds(100, 30, 250, 100);
scrollPanePlain.setVisible(true);
There are a number of issues
You need to add the JPanel groupBoxEncryption to the application JFrame
Don't add the textarea to the frame - components can only have one parent component
As already mentioned, you're using null layout which doesnt size components - forget about not a layout manager.
As JPanel uses FlowLayout by default, you need to override getPreferredSize for the panel groupBoxEncryption. Better yet use a layout manager such as GridLayout that automatically sizes the component
Example
JPanel groupBoxEncryption = new JPanel(new GridLayout());
Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or combinations of them, along with layout padding & borders for white space.
Suggest a preferred size for the text area in the number of rows and columns.
Add the text area to a scroll pane before then adding the scroll pane to the GUI.