My JFrame Consists of three main parts a banner at top scrollpane containing a JTextArea center and a JTextField at the bottom. When I re-size the frame I adjust the columns and rows in my JTextArea. When making the frame larger the JTextArea expands visually but removes the scroll-bar. Then if I make the frame smaller the JTextArea stays the same size. This Is where I attempt to re-size my JTextArea.
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
Why would the ScrollPane not re adjust to the change in size of the TextField.
The Rest of the code is below in case it is needed.
public class window extends JFrame
{
private static JFrame frame = new JFrame("Lillian");
private static JButton inputButton = new JButton("Send");
private static JTextField editTextArea = new JTextField(46);
private static JTextArea uneditTextArea = new JTextArea(26,50);
private static JPanel logoPanel = new JPanel();//Input text window
private static JPanel itextPanel = new JPanel();//Input text window
private static JPanel submitPanel = new JPanel();//Submit Button
private static JPanel bottom = new JPanel();//will contain scrollpane
private static JPanel middle = new JPanel();//willcontain itextpanel & submitbutton
private static JPanel otextPanel = new JPanel();//Text Output
public static void runWindow()
{
ImageIcon logo = new ImageIcon("Lillian_resize.png");//banner
ImageIcon icon = new ImageIcon("Lillian_icon.png");//application icon
frame.setIconImage(icon.getImage());
frame.setSize(660,640);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
logoPanel.setSize(10,10);
JLabel logoLabel = new JLabel(logo);
final JScrollPane scrollPane = new JScrollPane(otextPanel);//adds text to panel will scrollbar
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);//scrollbar only apears when more text than screen
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);//scrollbar never apears
scrollPane.setBorder(BorderFactory.createEmptyBorder());
logoPanel.add(logoLabel);
submitPanel.add(inputButton);
itextPanel.add(editTextArea);
otextPanel.add(uneditTextArea);
frame.getContentPane().add(logoPanel,"North");
frame.getContentPane().add(middle);
frame.getContentPane().add(bottom,"South");
middle.add(scrollPane,"North");//adds panels to outer panel
bottom.add(itextPanel, "West");
bottom.add(submitPanel, "East");
uneditTextArea.setLineWrap(true);
uneditTextArea.setWrapStyleWord(true);
uneditTextArea.setEditable(false);
uneditTextArea.setCaretPosition(uneditTextArea.getDocument().getLength());
frame.revalidate();//refreshes screen
//---------------wait for action------------
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
}
}
There should be no need to use a ComponentListener to resize components. That is the job of the layout managers that you use to dynamically resize the components.
You should not be adding the text area to a JPanel first. Instead when using text areas you would generally add the text area directly to the viewport of a JScrollPane by using code like:
JScrollPane scrollPane = new JScrollPane( textArea );
Then you add the scrollpane to the frame with code like:
frame.add(scrollPane, BorderLayout.CENTER);
As you have noticed you should also NOT use hardcoded literals like "Center". Instead use the variables provided by the layout manager. Since you are using a BorderLayout, use the variables defined in the BorderLayout class.
Also, you should NOT be using static variable to create your GUI. I suggest you read the section from the Swing tutorial on Layout Manager. The tutorial will give you more information and the example code will show you how to better structure your program so that you don't need to use static variables.
Related
Im trying to display to the user some text:
JTextField warningComponent = new JTextField(VERY_LONG_TEXT_NOENTERS);
warningComponent.setEditable(false);
but the window size is changed according to the text size. I want to set the window to be 30 X 40 all the time regardless of the warning text length.
And i want the warning text to be adjusted to the window size (maybe the user will have to scroll to see the end)
How do i do it?
Maybe i should use other swing component?
I tried most of the methods in JTextField class.
Thanks.
I add it to JPanel
Then the default layout manager should be a FlowLayout which will respect the preferred size of the text field.
To give a suggestion for the preferred size of the text field you need to do:
JTextField warningComponent = new JTextField(VERY_LONG_TEXT_NOENTERS, 20);
The second parameter will give a suggestion on how to size the text field to make approximately 20 characters visible at one time. You will then need to use the arrow keys to see the remaining characters.
And i want the warning text to be adjusted to the window size
If you want the textfield to resize according to the frame size and not the frame size following the dimension of the textfield, you may make use of specific layout to achieve that:
Using BorderLayout:
class MainPanel extends JPanel{
private JTextField txt;
public MainPanel(){
setLayout(new BorderLayout());
setPreferredSize(new Dimension(30, 40));
txt = new JTextField();
txt.setHorizontalAlignment(JTextField.HORIZONTAL);
add(txt);
}
}
Runner class to run to codes:
class TextFieldRunner{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
JFrame frame = new JFrame("Text Runner");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
You can try JScrollPane in your application, JScrollPane is scroll-able horizontally and vertically as you wish. And add JTextArea to JScrollPane. JTextField is not scroll-able.
Here is a small example:
JScrollPane scrollPane = new JScrollPane();
JTextArea textArea = new JTextArea();
scrollPane.add(textArea);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
This is the values for the scroll policy:
VERTICAL_SCROLLBAR_AS_NEEDED
VERTICAL_SCROLLBAR_NEVER
VERTICAL_SCROLLBAR_ALWAYS
HORIZONTAL_SCROLLBAR_AS_NEEDED
HORIZONTAL_SCROLLBAR_NEVER
HORIZONTAL_SCROLLBAR_ALWAYS
I'm trying to create a button and place it in a certain location, but for some reason it never goes in that specific location. I tried putting it a panel, using setBounds, using setLocation... but It doesn't seem to work...
I'm running this file in another file.
public class Inventory extends JPanel
{
private final static int frameWidth = 200;
private final static int frameHeight = 500;
private final static int screenLocationX = 100;
private final static int screenLocationY = 50;
private Panel panel;
private JFrame frame;
private JPanel jpanel;
public Inventory()
{
panel = new Panel();
frame = new JFrame();
JButton button = new JButton("Add Gem");
button.addActionListener(new Listener());
button.setPreferredSize(new Dimension(frameWidth,50));
// button.setLocation(0,400);
// button.setBounds(0,400,frameWidth,50);
panel.setVisible(true);
frame.setContentPane(panel);
frame.add(button);
frame.setVisible(true);
frame.setSize(frameWidth, frameHeight);
frame.setLocation(screenLocationX, screenLocationY);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
panel.addImage(new Gems());
}
}
}
Before adding panel to the frame use:
panel.setLayout(null); //setting the default settings of panel to null
and then use:
button.setBounds(300, 300, 300, 300); //bounding the button at specific location
this would work..
You need to turn the LayoutManager off
panel.setLayout(null);
JFrame by default uses a BorderLayout and, by default, components are added to the BorderLayout.CENTER position, unless otherwise specified
In this setup, the component will be placed on the centre of the frame and sized to fill it
Remember, each platform/OS renders content differently and these differences will change the amount of space required to display your components and all of this will effective the relationships between all the other components...
You consider changing the layout manager and using a combination of EmptyBorders and insets/padding to influence the location/size of your components. Try something like GridBagLayout or if your adventurous, checking out MigLayout
One of the first lessons you need to learn with GUI program (on just about any platform) is pixel perfect layouts are an illusion, there are too many variables which effect how content is rendered and how these can change the amount of space individual components will need in order to be displayed correctly...
I am creating a Java application which has a login screen. Right now I am designing the login screen. I use a Panel in a JFrame, which is positioned at BorderLayout.CENTER, and then set the layout of the Panel as GridLayout(3,1). Right now my application looks like this:
I want to design my JFrame like this:
Here the grey portion is the JFrame and the red portion is the Panel which has the login screen, TextField's and Button's. I don't want the TextField and Button's on the entire screen.
This is what I did right now
public class MailClient {
JFrame loginScreen;
JTextField emailid;
JPasswordField password;
JButton login;
Dimension loginScreenSize;
JPanel entireLogin;
BorderLayout mainLayout;
public static void main (String args[])
{
MailClient obj = new MailClient();
obj.build();
}
public void build()
{
mainLayout = new BorderLayout(40, 40);
loginScreenSize = new Dimension(300,300);
loginScreen = new JFrame("MailClient");
loginScreen.setSize(loginScreenSize);
loginScreen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loginScreen.setResizable(false);
loginScreen.setLocationRelativeTo(null);
loginScreen.setLayout(mainLayout);
entireLogin = new JPanel();
entireLogin.setLayout(new GridLayout(3,1));
emailid = new JTextField();
password = new JPasswordField();
login = new JButton("LOGIN");
entireLogin.add(emailid);
entireLogin.add(password);
entireLogin.add(login);
loginScreen.add(entireLogin, BorderLayout.CENTER);
loginScreen.setVisible(true);
}
}
Add an empty border of the thickness you find appropriate around the centered JPanel if you want it to have a border to the edge (if it resizes, for example).
myPanel.setBorder(new EmptyBorder(int, int, int, int))
Set the maximum size for the centered JPanel if you want to prevent it from being made larger by the BorderLayout CENTER normal workings.
myPanel.setMaximumSize(new Dimension(x, y))
I am creating a JPanel form which will contain several other JPanels. I want to place this inside a JScrollPane. Then I want to place the JScrollPane into a JTabbedPane as one of the tabs. I'm having a problem though -- my JPanel form winds up expanding when placed in the scrollpane even though I have set size, preferredsize, maximumsize, etc.
public class test
{
private static JFrame frame = new JFrame();
private static JTabbedPane pane0 = new JTabbedPane();
private static JScrollPane pane1 = new JScrollPane();
private static JPanel pane2 = new JPanel();
//add the rest of your JPanels here
public static void main(String[] args)
{
frame.setSize(400,400);
//add all the other attributes here
frame.add(pane0);
pane0.add(pane1);
pane1.add(pane2);
//go ahead and add the rest of your panels here
frame.pack();//resizes the frame so that its subcomponents fit well inside.
}
}//this last bracket is for the class itself. Sorry i couldn't tab everything the right //way.
Is this what you're trying to do? That's what i understood from your question. By the way, if your JPanel is expanding, change the size of your frame as well.
I am just trying to add a vertical scroll bar to my TextField and TextArea.
I am using a ScrollPane and it should create avertical/horizontal scroll bar by default.
Problem:
I need a vertical scroll bar to see the data which is not visible.
In the start a vertical scrollbar appears but when the data increases the vertical scrollbar changes to a horizontal scroll bar.
Also the TextField disappears and only a horizontal scrollbar appears in its place.
I guess it is because how I have set the bounds but I tried changing the bounds and it ends up completely doing away with the TextField.
My code snippet:
public JTextField inputField = new JTextField();
public JTextArea talkArea = new JTextArea();
public JScrollPane inputFieldScroll = new JScrollPane(inputField);
public JScrollPane talkAreaScroll = new JScrollPane(talkArea);
talkArea.setEditable(false);
talkArea.setBackground(Color.white);
talkAreaScroll.setBounds(new Rectangle(TALK_LEFT, TALK_TOP, TALK_WIDTH, TALK_HEIGHT));
this.getContentPane().add(talkAreaScroll, null);
//set input area
inputField.setBackground(Color.white);
inputField.setBounds(new Rectangle(INPUT_LEFT, INPUT_TOP, INPUT_WIDTH, INPUT_HEIGHT));
inputFieldScroll.setVerticalScrollBar(new JScrollBar());
inputFieldScroll.setBounds(new Rectangle(INPUT_LEFT, INPUT_TOP, INPUT_WIDTH, INPUT_HEIGHT));
Question:
Is there some parameter I need to set so that it remains a vertical scroll bar?
Why does the input scroll bar occupy the whole inputfield when the data becomes a huge line? It appears as a proper vertical scrollbar in the start.
Any advice appreciated.
Thanks
Below is a small compilable code snippet I mentioned above. I agree with camickr that you should not be using absolute positioning but rather use the layout managers. If you absolutely need to have a horizontal scrollbar for the JTextField, then one way to get it to work is to have it show up always, using the JScrollPane constructor that allows for this. i.e,
JScrollPane inputPane = new JScrollPane(inputField, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
For e.g.,
import java.awt.*;
import javax.swing.*;
public class FuSwing1b extends JPanel {
private static final int TA_ROWS = 25;
private static final int TA_COLS = 60;
private JTextField inputField = new JTextField();
private JTextArea talkArea = new JTextArea(TA_ROWS, TA_COLS);
public FuSwing1b() {
talkArea.setEditable(false);
talkArea.setFocusable(false);
talkArea.setBackground(Color.white);
//talkArea.setPreferredSize(new Dimension(TALK_WIDTH, TALK_HEIGHT));
JScrollPane talkPane = new JScrollPane(talkArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane inputPane = new JScrollPane(inputField, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
int gap = 10;
setLayout(new BorderLayout(gap, gap));
add(talkPane, BorderLayout.CENTER);
add(inputPane, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(gap , gap, gap, gap));
}
private static void createAndShowUI() {
JFrame frame = new JFrame("FuSwing1b");
frame.getContentPane().add(new FuSwing1b());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Don't play with the bounds. Use a layout manager and you won't have to worry about this.
When you create the text field use something like:
JTextField textField = new JTextField(10);
This will create a text field that will hold a minimum of 10 characters. If the number of characters exceeds the display width of the text field the use can see the remaining characters by using the right/left arrow keys. That is the normal UI used by all applications I have ever seen. Don't try to create your own UI by using a horizontal scrollbar. Users are not accustomed to that.
for the text area you can create it using:
JTextArea textArea = new JTextArea(5, 30);
JScrollPane scrollPane = new JScrollPane( textArea );
to create a text area with 5 rows and approximately 30 character per row.
Now add the text field and the scrollpane to your frame "using layout managers" and then pack the frame. The layout managers will determine the best size for the compoents. Scrollbars will automatically appear on the text area as you add text to it and the text exceeds 5 lines.