I made a program and I want to add a JScrollPane to a JTextArea (but it doesn't show up).
Here's the code (or at least everything that has to deal with the JTextArea / JScrollPane, the whole code is a lot):
static JPanel contentPane; // This one got initialised in the constructor
static JTextArea tarMessages;
public void addTextArea{
tarMessages = new JTextArea();
tarMessages.setForeground(Color.WHITE);
tarMessages.setBackground(new Color(0, 0, 0, 0));
tarMessages.setEditable(false);
tarMessages.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
tarMessages.setBounds(600, 124, 200, 192);
tarMessages.setOpaque(false);
/*DefaultCaret dlcMessages = (DefaultCaret)tarMessages.getCaret();
dlcMessages.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);*/
tarMessages.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e) {
requestFocus();
}
});
JScrollPane scpMessages = new JScrollPane(tarMessages);
scpMessages.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scpMessages.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scpMessages.setPreferredSize(new Dimension(10, 192));
scpMessages.setEnabled(true);
contentPane.add(scpMessages);
contentPane.add(tarMessages);
}
Thank you for helping. Have nice holidays.
JScrollPane scpMessages = new JScrollPane(tarMessages);
...
contentPane.add(scpMessages);
contentPane.add(tarMessages);
A Swing component can only have a single parent.
First you add the text area to the scroll pane, which is correct.
But then you remove it from the scroll pane when you add it to the content pane.
Get rid of:
///contentPane.add(tarMessages);
Also, when you create the text area use code like:
tarMessages = new JTextArea(5, 20);
This will specify the rows/columns of the text area so it can size itself appropriately.
Don't use setBounds(...)
Related
So, in the code below I have a JTextArea on the left side. A JScrollPane on the upper right side that looks fine. Using the same code I also add a JScrollPane on the lower right side, but despite identical code, save the preferred sizes and absolute positioning, the vertical scroll bar does not seem to show up.
I will add a screenshot of the GUI after the code. Thank you in advance for any help resolving this issue.
frame = new JFrame("Title");
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().setPreferredSize(new Dimension(width, height));
frame.pack();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
frame.setResizable(false);
frame.addKeyListener(this);
//scroll and text area
textArea = new JTextArea();
textArea.setText("Static Text\n");
textArea.setFont(new Font("Consolas", 0, 12));
textArea.setColumns(50);
textArea.setLineWrap(true);
textArea.setEditable(false);
scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(width/2, height * 4 / 5));
scrollPane.setBounds(width/2, 0, width/2, height * 4 / 5);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(scrollPane);
inputTextArea = new JTextArea();
inputTextArea.setText(">");
inputTextArea.setFont(new Font("Consolas", 0, 12));
inputTextArea.setColumns(50);
inputTextArea.setLineWrap(true);
inputScrollPane = new JScrollPane(inputTextArea);
inputScrollPane.setPreferredSize(new Dimension(width/2, height / 5));
inputScrollPane.setBounds(width/2, height * 4 / 5, width, height);
inputScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(inputScrollPane);
//map
mapView = new JTextArea();
mapView.setFont(new Font("Consolas", 0, 8));
mapView.setEditable(false);
mapView.setPreferredSize(new Dimension(width/2, height));
mapView.setText(state.getCurrentMap().toString());
mapView.addKeyListener(this);
mapView.setBounds(0, 0, width/2, height);
frame.add(mapView);
frame.pack();
frame.setVisible(true);
You've several significant issues with that code including
Use of null layouts. 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. This is making your debugging work more difficult, believe me. For that reason you're far better off learning about and using the layout managers. You can find the layout manager tutorial here: Layout Manager Tutorial, and you can find links to the Swing tutorials and to other Swing resources here: Swing Info.
You're setting the sizes/bounds of your JTextAreas. This prevents them from expanding appropriately when text is added, and will prevent scrollbars from the surrounding JScrollBars from appearing. Set the JTextArea column and row properties instead.
Adding a KeyListener to your text components. While this is not causing your current error, it is something that should be avoided and will often mess with the function of the component. Much better to use higher level listeners such as DocumentListener or DocumentFilter.
For example, the code below shows how to use simple layouts, text area column and row properties, as well as use of key bindings to capture the user's pressing the enter key, in case this is desired:
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class LayoutExample extends JPanel {
private static final int MV_ROWS = 65;
private static final int MV_COLS = 100;
private static final int TA_ROWS = 34;
private static final int TA_COLS = 54;
private static final int ITA_ROWS = 8;
private static final Font MV_FONT = new Font("Consolas", 0, 8);
private static final Font TA_FONT = new Font("Consolas", 0, 12);
private JTextArea mapView = new JTextArea(MV_ROWS, MV_COLS);
private JTextArea textArea = new JTextArea("Static Text\n", TA_ROWS, TA_COLS);
private JTextArea inputTextArea = new JTextArea(ITA_ROWS, TA_COLS);
public LayoutExample() {
mapView.setFont(MV_FONT);
mapView.setEditable(false);
mapView.setFocusable(false);
JScrollPane mvScrollPane = new JScrollPane(mapView);
textArea.setFont(TA_FONT);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
textArea.setFocusable(false);
JScrollPane taScrollPane = new JScrollPane(textArea);
taScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setEnterKeyBindings(inputTextArea);
inputTextArea.setFont(TA_FONT);
inputTextArea.setLineWrap(true);
inputTextArea.setWrapStyleWord(true);
JScrollPane itaScrollPane = new JScrollPane(inputTextArea);
itaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel rightPanel = new JPanel(new BorderLayout());
rightPanel.add(taScrollPane, BorderLayout.CENTER);
rightPanel.add(itaScrollPane, BorderLayout.PAGE_END);
setLayout(new GridLayout(1, 0));
add(mvScrollPane);
add(rightPanel);
inputTextArea.setText(">");
}
// to capture the "enter" key being pressed without having to use a
// KeyListener
private void setEnterKeyBindings(final JTextArea textComponent) {
// only accept input when this component is focused
int condition = WHEN_FOCUSED;
InputMap inputMap = textComponent.getInputMap(condition);
ActionMap actionMap = textComponent.getActionMap();
// only will bind one keystroke -- that for enter key
KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enterKeyStroke, enterKeyStroke.toString());
// action to take if enter is pressed
actionMap.put(enterKeyStroke.toString(), new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// get text from input text area, and then clear text
String text = textComponent.getText();
textComponent.setText(">");
// append this text to the upper text area
textArea.append(text + "\n");
// TODO: send text elsewhere via chat?
}
});
}
private static void createAndShowGui() {
LayoutExample mainPanel = new LayoutExample();
JFrame frame = new JFrame("Title");
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());
}
}
I made a simple program in Java that contains only one text area and a button. The button is suppose to add a "text". However, it doesn't work for me.
On a side note: I'm trying to keep my functions as short as possible. (I don't want a function with too many line of codes)
First, I create the JFrame
private static void createFrame()
{
//Build JFrame
JFrame frame = new JFrame("Text Frame");
frame.setLayout(null);
frame.setSize(500,400);
Container contentPane = frame.getContentPane();
contentPane.add(textScrollPane());
contentPane.add(buttonAddText());
//Set Frame Visible
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
Then the TextArea and the Scrollpane (for adding scrollbar)
private static JTextArea textArea()
{
JTextArea output = new JTextArea();
output.setLineWrap(true); // Text return to line, so no horizontal scrollbar
output.setForeground(Color.BLACK);
output.setBackground(Color.WHITE);
return output;
}
private static JScrollPane textScrollPane()
{
JScrollPane scrollPane2 = new JScrollPane(textArea());
scrollPane2.setBounds(0, 0, 490, 250);
return scrollPane2;
}
And finally, the button
private static JButton buttonAddText()
{
JButton testbutton = new JButton("TEST");
testbutton.setBounds(20, 280, 138, 36);
testbutton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e)
{
//action listener here
textArea().insert("TEXT",0);
System.out.println("Button Tested!");
}
});
return testbutton;
}
When I click on the button, it doesn't do anything.
I just want a text to be added in the JTextArea. Did I forget something?
textArea() is returning a new JTextArea everytime it is called. Therefore your buttonAddText() function is calling textArea() and adding text to a newly created text area that is not contained in the scroll pane.
You need to pass a reference of the text area to the textScrollPane() and the buttonAddText() functions.
Something like this would work:
JTextArea jta = textArea();
contentPane.add(textScrollPane(jta));
contentPane.add(buttonAddText(jta));
Change textScrollPane() and buttonAddText() so that they accept a JTextArea parameter and don't call textArea() in these functions anymore to create new text areas. Instead use the JTextArea object which is passed into the functions.
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.
public class DailogDemo
{
private JDialog chatdailog;
private JTextArea chatHistory;
private JScrollPane mScrollMessage;
DailogDemo()
{
chatdailog=new JDialog();
chatdailog.setSize(300, 400);
chatHistory=new JTextArea();
chatHistory.setPreferredSize(new Dimension(150,100));
mScrollMessage=new JScrollPane();
mScrollMessage.add(chatHistory);
mScrollMessage.setBounds(4, 10, 150, 100);
mScrollMessage.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
chatdailog.add(mScrollMessage);
chatdailog.show();
}
public static void main(String args[])
{
new DailogDemo();
}
}
In the above code, I can't able to see the JTextArea in JScrollPane. Does anybody know what I am doing wrong?
use JTextArea(int rows, int columns)
don't set and remove chatdailog.setSize(300, 400);
don't set and remove chatHistory.setPreferredSize(new Dimension(150,100));
don't set and remove mScrollMessage.add(chatHistory); use JScrollPane scrollPane = new JScrollPane(textArea); instead
don't set and remove mScrollMessage.setBounds(4, 10, 150, 100);
don't set and remove chatdailog.show(); use chatdailog.setVisible(true);
add code line chatdailog.pack() before line chatdailog.setVisible(true);
if is there another parent for this JDialog wrap chatdailog.setVisible(true); into invokeLater()
If you have a layout, you can use new JTextArea(24, 32) and pack() to get a nice arrangement.
set size for JTextArea
chatHistory.setSize(new Dimension(width,height));
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.