How to make a JTextArea scrollable but still have a height set? - java

I have a Java application that connects to a device and shows the log in a JTextArea. I want the JTextArea to be scrollable, which I have achieved by putting it inside a JScrollPane. The JScrollPane containing the JTextArea is in the CENTER part of a BorderLayout. I use pack() to set the JFrame's size just before it is shown. However, this has some problems:
With no height set for the JTextArea it is very thin, and the text can't be seen very well (in the second picture there is actually text):
With a preferred size set for the JTextArea it seems to work fine at first. But when there is more text the scrollbars do not appear as expected. They appear when the JFrame is resized down regardless of the amount of text in the JTextArea. This also doesn't show all the text via scrolling.
Also, setting a minimum height doesn't help; it leads to the same result as in the first case.
My code for initializing the frame:
JButton connectBtn, disconnectBtn;
JTextArea logArea;
public MyApplication() throws HeadlessException {
super();
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new MyWindowListener()); // Disconnect and exit on close
setLayout(new BorderLayout());
connectBtn = new JButton("Connect");
disconnectBtn = new JButton("Disconnect");
disconnectBtn.setEnabled(false);
connectBtn.addActionListener(new ConnectListener()); // Connects to device
disconnectBtn.addActionListener(new DisconnectListener()); // Disconnects from device
logArea = new JTextArea();
logArea.setEditable(false);
// Whatever fixes the problem goes here... e.g.
// logArea.setPreferredSize(new Dimension(100, 200));
JPanel buttons = new JPanel(new BorderLayout());
buttons.add(connectBtn, BorderLayout.LINE_START);
buttons.add(disconnectBtn, BorderLayout.LINE_END);
add(buttons, BorderLayout.PAGE_START);
add(new JScrollPane(logArea), BorderLayout.CENTER);
pack();
setVisible(true);
}

Don't play with the sizes.
Specify the rows/column that you want in the text area and the text area will calculate its own preferred size.
//logArea = new JTextArea();
logArea = new JTextArea(5, 20);

Related

Add JButton to JScrollPame

I have the following code taken from GeeksforGeeks that displays the contents of a 2-d array in JTable using JScrollPane:
public class JTableExamples {
// frame
JFrame f;
// Table
JTable j;
// Constructor
JTableExamples()
{
// Frame initiallization
f = new JFrame();
// Frame Title
f.setTitle("JTable Example");
// Data to be displayed in the JTable
String[][] data = {
{ "Kundan Kumar Jha", "4031", "CSE" },
{ "Anand Jha", "6014", "IT" }
};
// Column Names
String[] columnNames = { "Name", "Roll Number", "Department" };
// Initializing the JTable
j = new JTable(data, columnNames);
j.setBounds(30, 40, 200, 300);
// adding it to JScrollPane
JScrollPane sp = new JScrollPane(j);
f.add(sp);
// Frame Size
f.setSize(500, 200);
// Frame Visible = true
f.setVisible(true);
}
What I am trying to do is add a simple Component (like JButton) underneath the table but it does not seem to work. I tried modifying the code by adding the JButton to JPanel and adding JPanel to the frame:
JButton button = new JButton("Back");
JPanel panel = new JPanel();
panel.add(button);
f.add(sp);
f.add(panel);
But this simply deletes the entire table and replaces it with a single button. I also tried adding the button to JPanel and adding that JPanel to JScrollPane:
JButton button = new JButton("Back");
JPanel panel = new JPanel();
panel.add(button);
sp.add(panel);
f.add(sp);
But this did not seem to change anything. I also tried to tinker with preferred and maximum size of JScrollPanel to no avail - it always occupies the entire screen and prevents JButton from appearing on the screen.
Not shooting for design here, just functionality: have a JButton appear underneath my JTable. Any suggestions will be greatly appreciated. Thank you in advance!
The default layout manager of a JFrame is the BorderLayout.
f.add(sp);
f.add(panel);
When you don't specify a constraint for the BorderLayout the CENTER is assumed. You can only have a single component added to the CENTER.
Instead your code should be:
f.add(sp, BorderLayout.CENTER);
f.add(panel, BorderLayout.PAGE_END);
Note the default layout manager for a JPanel is the FlowLayout. So the button will be horizontally centered in the panel.
Also, instead of using a JPanel, try adding the button directly to the PAGE_END of the frame to see the difference.
Read the section from the Swing tutorial on Using Layout Manager for more information and examples for using each of the different layout managers to understand the differences of the above suggestions.
Edit:
Is there a way to decrease the height of the table
If you know you have a small table then you can use:
table.setPreferredScrollableViewportSize(table.getPreferredSize());
This will make the scroll pane the size of the table.
Then you use:
//f.setSize(500, 200);
f.pack();
Now all components will be displayed at their preferred size.

Java - Swing - TextArea - scrollbar

I want to have a textArea to display results that can be scrolled. The scrollbar doesn't appear even though I set it to VERTICAL_SCROLLBAR_ALWAYS
What Am I doing wrong??
void addPlayerPanel(JFrame gameFrame) {
JPanel playerPanel = new JPanel();
// automatically added to contentPane with gameFrame.add()
gameFrame.add(playerPanel, BorderLayout.CENTER);
playerPanel.setBorder(new TitledBorder(new EtchedBorder(), "Registered players"));
// text are to show registered players
JTextArea display = new JTextArea(5, 40);
display.setEditable(true); // set textArea to editable
display.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
JScrollPane scroll = new JScrollPane(display);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
// Add Text area
playerPanel.add(scroll);
playerPanel.add(display);
}
You're adding both the JScrollPane AND it's display to the GUI -- DON'T do that. Add just the JScrollPane. It holds the display and that is what you need.
So change:
playerPanel.add(scroll);
playerPanel.add(display);
to
playerPanel.add(scroll);
// playerPanel.add(display);
Question: why are you setting the layout manager of your JTextArea? That really makes little sense.

JLabel wont change Width

I'm programming right now a Chomp Game for Uni. Everything works fine but the Label at the bottom. Its background is supposed to fill out the entire bottom. In the attachment you can see how it instead looks now. I tried setting the minimum and the preferred size of the label. The Height is changing but the width just stays adjusted to the text. How can I change that?
Note: The snippet only contains the setting up of the Frame and Panels in a custom method and not the main class.
private void init()
{
JFrame fenster = new JFrame();
this.spielfeld = new SpielfeldPanel(M, N);
this.anzeige = new SpielerAnzeigeLabel(this.spieler);
JPanel panel = new JPanel();
BoxLayout boxlayout = new BoxLayout(panel,BoxLayout.Y_AXIS);
panel.setLayout(boxlayout);
fenster.setTitle("Chomp");
fenster.setSize(1000,700);
panel.setPreferredSize(new Dimension(1000, 60));
Dimension d = new Dimension(getPreferredSize());
panel.setMinimumSize(d);
panel.add(spielfeld);
panel.add(anzeige);
fenster.add(panel);
this.spielfeld.setVisible(true);
this.anzeige.setVisible(true);
panel.setVisible(true);
fenster.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
A BoxLayout respects the width of the component to the label is displayed at its preferred width/height.
A JFrame uses a BorderLayout by default. So just add the label to the frame independently of the panel:
//panel.add(anzeige);
//fenster.add(panel);
fenster.add(panel, BorderLayout.CENTER);
fenster.add(anzeige, BorderLayout.PAGE_END);
The PAGE_END constraint respects the height but makes the width equal to the space available. Read the section from the Swing tutorial on How to Use BorderLayout for more information and examples.

how to add scrollbar to textarea in java

the jscrollpane that I am adding doesnt appearin my textarea
textArea = new JTextArea();
scroll = new JScrollPane(textArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(textArea);
this.add(scroll);
this.setSize(1000, 600);
this.setLayout(new BorderLayout());
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
textArea = new JTextArea();
scroll = new JScrollPane(textArea);
//this.add(textArea); // get rid of this
this.add(scroll);
You create the scrollpane with the text area, but then the next statement removes the text area from the scrollpane because a component can only have a single parent.
Get rid of that statement and just add the scrollpane to the frame.
Then scrollbars will appear automatically as you add data to the text area.
Also you should create the text area using something like:
textArea = new JTextArea(5, 20);
to give a suggestion on how big to make the text area.
I did what you said but still nothing happens
Another problem is that you need to set the layout manager BEFORE you start adding components to the frame (or panel).
Remove this.add(textArea); and add scroll.setSize( 100, 100 ); will also work for you.

JButton Appears on One Computer, But Not Others (BorderLayout)

I am new to Swing. I am building a JFrame with a JScrollPane inside it using Eclipse IDE. Inside of the JScrollPane is a JPanel in Border Layout. I tried to add a JButton (called "submitAnswers") to the JFrame using the code below, but for some reason the button only appears at the end of the frame on my computer, but not on other computers (my friend tried it on his Mac and I tried it on a separate Windows OS like mine). Some proposed solutions that I have tried and from other sites that have not worked include:
Use the pack() method. Reason: since the preferred size of the JPanel is much longer in height than the JFrame (hence I employed a JScrollPane), packing the JFrame only causes the text to be not visible on the desktop.
Place button on content JPanel. Reason: I don't know. It just wouldn't appear on another desktop computer or my friend's mac computer.
Use BorderLayout.SOUTH instead of BorderLayout.PAGE_END. Reason: There was absolutely no change. The button would still be visible on my computer, but invisible on others.
Place button directly on JFrame. Reason: I don't know.
In addition, my JFrame is nested within a static method; hence, I've only included the relevant code for the specific method I'm having issues with.
Has anyone had this issue before? I would really appreciate your insight.
Code:
public static void createTestPage() {
JFrame testFrame = new JFrame("testing...1,2,3");
//Customizes icon to replace java icon
try {
testFrame.setIconImage(ImageIO.read(new File("src/icon.png")));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//Centers location of introFrame to center of desktop
Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
testFrame.setLocation(screenDimensions.width / 16,screenDimensions.height / 14);
//Size and display the introFrame.
Insets insets = testFrame.getInsets();
//Format size of screen itself
testFrame.setSize(1200 + insets.left + insets.right,
400 + insets.top + 250 + insets.bottom);
//Temporarily set screen so that it cannot be resized
testFrame.setResizable(false);
//Set background color of testFrame
testFrame.getContentPane().setBackground(new Color(75, 0, 130));
testFrame.setLayout(new BorderLayout());
//Set layout of testFrame
testFrame.setLayout(new BorderLayout(10, 1));
//Test content
JPanel testContentPanel = new JPanel();
testContentPanel.setBackground(new Color(75, 0, 130));
testContentPanel.setSize(new Dimension(900,2060));
testContentPanel.setPreferredSize(new Dimension(900, 2060));
//Test content pane layout
testContentPanel.setLayout(new BoxLayout(testContentPanel, BoxLayout.PAGE_AXIS));
//Create panel to hold instructions text
JPanel instructionsPanel = new JPanel();
instructionsPanel.setBackground(new Color(75, 0, 130));
instructionsPanel.setLayout(new BorderLayout(10,1));
//Create JPanel for submit answers button
JPanel submitAnswersPanel = new JPanel(new BorderLayout());
submitAnswersPanel.setBackground(new Color(75, 0, 130));
submitAnswersPanel.setVisible(true);
//Create button to submit personality test answers
JButton submitAnswers = new JButton("Submit Answers");
submitAnswers.setVisible(true);
submitAnswers.setBorder(new EmptyBorder(10, 400, 10, 400));
//Add submitAnswers button to panel
submitAnswersPanel.add(submitAnswers);
//Add submitAnswersPanel to test content panel
testContentPanel.add(submitAnswersPanel);
//Create scroll pane to allow for scrollable test (contents cannot fit one page)
JScrollPane testScrollPane = new JScrollPane();
testScrollPane.setViewportView(testContentPanel);
//Get rid of horizontal scroll bar and add vertical scrollbar
testScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
testScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Speed up scrolling
testScrollPane.getVerticalScrollBar().setUnitIncrement(16);
testFrame.add(testScrollPane);
//Experiment to show button
testFrame.setVisible(true);
}
I've refactored your code a little to use method to create the individual components of the GUI. You can find the full code at this ideone link
What I saw when I first copied your code to my machine was that the only thing visible was the button. So I create all the components in their own methods and then added them to the frame and panels using the Border Layout. This then enabled me to put the instructions in the NORTH sections, the button in the SOUTH section and then the main bits would go in the CENTER section.
One thing to note about the sections: (From the documentation)
The components are laid out according to their preferred sizes and the constraints of the container's size. The NORTH and SOUTH components may be stretched horizontally; the EAST and WEST components may be stretched vertically; the CENTER component may stretch both horizontally and vertically to fill any space left over.
So you should add the component you want to scale in size to the CENTER section.
My main method now looks like this:
public static void main(final String[] args) {
final JButton submitAnswers = createSubmitAnswersButton();
final JPanel instructionsPanel = createInstructionsPanel();
final JPanel testContentPanel = createContentPanel();
testContentPanel.add(instructionsPanel, BorderLayout.NORTH);
testContentPanel.add(submitAnswers, BorderLayout.SOUTH);
final JScrollPane scrollingContentPane = createScrollPaneFor(testContentPanel);
final JFrame testFrame = createJFrame();
testFrame.add(scrollingContentPane, BorderLayout.CENTER);
testFrame.setVisible(true);
}

Categories

Resources