I am a beginer at programing and i wanted to add a scroll panel to a JTextArea so i tried to research tutorials online. i followed the examples but its not working can someone plz tell me what i am doing wrong. thank you so much
public View(Model model) {
this.model = model;
setBounds(100,50, 800, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
addDisplay(c);
addButtons(c);
addTxt(c);
}
private void addDisplay(Container c){
JPanel p = new JPanel();
addTxt2(p);
addTxt(p);
add(p, "North");
}
private void addTxt(JPanel p){
txt = new JTextArea(15, 35);
txt.setBackground(Color.BLACK);
txt.setForeground(Color.WHITE);
txt.setEditable(true);
JScrollPane scroll= new JScrollPane (txt);
p.add(scroll);
}
Always invoke revalidate and repaint after adding any components to a JPanel
p.add(scroll);
p.revalidate();
p.repaint();
From the use of setBounds, it appears that there is no layout manager in use. Don't use absolute positioning (null layout). By default, components have a size of 0 x 0 so will not appear unless their size is set. A layout manager should be used here instead.
Post an SSCCE for better help sooner
You have to set the bounds of your scroll setBounds(int, int, int, int)
and define the area of your JTextArea
Here's an example:
public class ScrollingTextArea extends JFrame {
JTextArea txt = new JTextArea();
JScrollPane scrolltxt = new JScrollPane(txt);
public ScrollingTextArea() {
setLayout(null);
scrolltxt.setBounds(3, 3, 300, 200);
add(scrolltxt);
}
public static void main(String[] args) {
ScrollingTextArea sta = new ScrollingTextArea();
sta.setSize(313,233);
sta.setTitle("Scrolling JTextArea with JScrollPane");
sta.show();
}
}
I've found it here
Related
i been working on some bigger project lately but couldn't figure it out why JScrollPane wouldn't work. I have never used it before and I read many solved problems about it on stackOverflow and other programming forums but non of the code were looking similar to mine to help me implement my method.
this is new project i made to make it short and show some examples.
Red colour is main panel that will contain another panel/JScrollPane inside that will be colour black
and i would like to make this Jpanel with colour black to be scrollable and hold any number of that white JPanels that might be from 0 to a 100+
public class ScrollablePane {
private JFrame frame;
private JPanel panelCopy;
private JPanel panel;
private JPanel container;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ScrollablePane window = new ScrollablePane();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ScrollablePane() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
panel = new JPanel();
panel.setBackground(Color.RED);
panel.setBounds(0, 0, 434, 261);
frame.getContentPane().add(panel);
panel.setLayout(null);
container = new JPanel();
container.setBackground(Color.BLACK);
container.setBounds(10, 10, 414, 241);
container.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
panel.add(container);
for(int i = 0; i < 20; i++) {
if(i > 0) {
panelCopy = new JPanel();
panelCopy.setPreferredSize(new Dimension(400, 40));
container.add(panelCopy);
}
}
}
}
if you want to use a JScrollPane, then your code actually needs to use a JScrollPane. The code you posted doesn't even create a JScrollPane.
If you want the panels to display vertically then don't use a FlowLayout. The FlowLayout is a horizontal layout. You could use a BoxLayout or a GridBagLayout.
Why do you create the "panel" variable and add it the the content pane? The content pane of the frame already is a JPanel that uses a BorderLayout. There is no need to add another panel
Don't use a null layout!!! Swing was designed to be used with layout managers. Scrolling won't work if the panel added to the scroll pane uses a null layout.
So in your case the basic logic might be something like:
Box container = Box.createVerticalBox();
// add you child panels to the container.
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(container, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(wrapper);
frame.add(scrollPane, BorderLayout.CENTER);
Note the "wrapper" panel is used to prevent the panels from expanding in size when the scroll pane is larger then the preferred size of the "container" panel.
Try:
//JScrollPane scrollPane = new JScrollPane(wrapper);
JScrollPane scrollPane = new JScrollPane(container);
to see the different result.
I'm trying to understand how Java.awt works (we need to create a GUI without GUI editor)
the following code does not show 2 TextAreas:
Frame fr = new Frame("Parser");
Panel buttons = new Panel();
Panel inputText = new Panel();
Panel outputText = new Panel();
String here = new String ("Insert code here...");
TextArea input = new TextArea(here, 9, 96, TextArea.SCROLLBARS_VERTICAL_ONLY);
TextArea output = new TextArea(here, 9,96,TextArea.SCROLLBARS_VERTICAL_ONLY);
public Window(){
fr.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
fr.dispose();
}
}
);
fr.setSize(700, 400);
fr.setLocation(200,100);
fr.setResizable(false);
fr.add(buttons);
fr.add(inputText);
fr.add(outputText);
buttons.setBounds(new Rectangle(0,0,700,60));
buttons.setBackground(new Color(200,200,200));
inputText.setBounds(new Rectangle(0,60,700,170));
inputText.setBackground(new Color(255,255,255));
inputText.add(input);
outputText.setBounds(new Rectangle(0,230,700,170));
outputText.setBackground(new Color(200,200,200));
outputText.add(output);
}
Obtained result:
Expected result:
Your code does not respect the layout managers that your containers are using. I believe that AWT Frames use a BorderLayout by default (edit: yes they do, per the Frame API. Suggestions:
In general avoid AWT for Swing which has much greater power and flexibility, although it too is showing its age, just less so than AWT.
Read up on and use layout managers in a smart way to do your heavy lifting for you. Here it looks like a BoxLayout could help you.
Avoid use of null layouts. While yes, that could offer you a quick and easy fix for your current code, it leads to the creation of 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.
Avoid setting bounds, sizes or locations of any components, and again let the components and their container's layout managers set the sizes for you.
The Layout Manager Tutorial
For example:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;
public class MyWindow extends JPanel {
private static final int ROWS = 10;
private static final int COLS = 50;
private static final String[] BUTTON_NAMES = { "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday" };
private static final int GAP = 3;
private JTextArea inputTextArea = new JTextArea(ROWS, COLS);
private JTextArea outputTextArea = new JTextArea(ROWS, COLS);
public MyWindow() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
for (String btnName : BUTTON_NAMES) {
buttonPanel.add(new JButton(btnName));
}
outputTextArea.setFocusable(false);
outputTextArea.setEditable(false);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(buttonPanel);
add(putInTitledScrollPane(inputTextArea, "Input Text"));
add(putInTitledScrollPane(outputTextArea, "Output Text"));
}
private JPanel putInTitledScrollPane(JComponent component,
String title) {
JPanel wrapperPanel = new JPanel(new BorderLayout());
wrapperPanel.setBorder(BorderFactory.createTitledBorder(title));
wrapperPanel.add(new JScrollPane(component));
return wrapperPanel;
}
private static void createAndShowGui() {
MyWindow mainPanel = new MyWindow();
JFrame frame = new JFrame("MyWindow");
frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
}
});
}
}
Which displays as:
Use of layout managers gives you much greater ease when it comes to changing or enhancing your GUI. For example, since I'm setting my JTextArea's width with a COL constant, if I change the COL constant, the whole GUI widens, even the buttons and the button JPanel, since the layout managers are handling all the sizing. With your code, you'd have to manually change the width of every component added to the GUI, which is prone to bug creation.
Because you are manually laying out your components, you are needed to set layout to null (setLayout(null);)
so before adding any component add this line in your code.
fr.setLayout(null);
Now you will get this :
I have tried several ways, but still havent found the solution. I have a jgraph in a frame and I want to add a Jbutton in that frame also in a specific location. However I only get one of them when i run the program, because they expand to the whole window. Any ideas how to fix this?
Thanks in advance.
public class GUIquery extends JFrame {
JFrame frame;
static JGraph jgraph;
final mxGraph graph = new mxGraph();
final mxGraphComponent graphComponent = new mxGraphComponent(graph);
public GUIquery() {
super("Test");
GraphD();
imgbtn();
}
public void GraphD() {
Object parent = graph.getDefaultParent();
graph.getModel().beginUpdate();
try {
........
}catch {
........
} finally {
graph.getModel().endUpdate();
}
getContentPane().add(graphComponent);
}
public void imgbtn() {
JPanel jpanel = new JPanel();
jpanel.setSize(100, 100);
jpanel.setLocation(1200, 60);
JButton imgbtn = new JButton("Export as Image");
imgbtn.setSize(100, 100);
imgbtn.setLocation(1200, 60);
jpanel.add(imgbtn);
add(jpanel);
}
public static void main(String[] args) {
GUIquery frame = new GUIquery();
frame.setLayout(null);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 320);
frame.setVisible(true);
}
}
Don't use null layouts. They inevitably result in trouble.
From your code snippet it is impossible to tell where you want them to be relative to each other, the following puts the button below the graph.
The content pane uses BorderLayout by default. For BorderLayout, you need to use place components at different positions:
// the default position, but it does not hurt to be explicit
add(graph, BorderLayout.CENTER);
...
// and the panel
add(jpanel, BorderLayout.SOUTH);
If the positioning is not what you want, take a look at the visual guide to layout managers to pick the layout manager that suits your needs best.
In the button panel the setLocation() and setSize() calls are useless. The layout manager of the panel is responsible for setting the button's bounds. If the default FlowLayout is not what you want for it, use the guide to pick another for the panel too.
I have a situation like this.
I have scrollpane whose viewportView is a JPanel
And that JPanel has the layout as BoxLayout. In this panel I add one class which extends JPanel and that class contains JComponents.
So while running an application, the JComponents are shown in the JScrollPane.
This is how my ScrollPane is formed.
The problem here is, When the data exceeds more than around 750 rows, The scrollbar starts giving problems.
When scrolling up or down by mouse wheel, scroll doesnot move smoothly, It suddenly stops in the middle and again starts, say it has a jerky movement.
my Question is how can i get the smooth mouse movement in this scenario.
My scrollPane is like this
public JScrollPane getScrollPane() {
if (scrollPane == null) {
scrollPane = new JScrollPane();
scrollPane.setSize(new Dimension(1000, 433));
scrollPane.setLocation(new Point(10, 10));
scrollPane.setColumnHeaderView(getHeaderOfRowPanel());
scrollPane
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setViewportView(getScrollPanel());
scrollPane
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.getVerticalScrollBar().setUnitIncrement(
unitIncrement);
}
return scrollPane;
}
private JPanel getScrollPanel() {
if (scrollPanel == null) {
scrollPanel = new JPanel();
scrollPanel.setBorder(null);
scrollPanel.setLayout(new BoxLayout(getScrollPanel(),
BoxLayout.Y_AXIS));
}
return scrollPanel;
}
private class RowPanel extends JPanel {
//My components are here ..
//I add this Panel in scrollPanel
}
Have look at JScrollBar.setUnitIncrement, beacuse bunch of JPanels in the JScollPane has un_natural scrolling in compare with JList, JTable or JTextArea
example
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JScrollBarUnitIncrement {
public static void main(String[] args) {
final JFrame f = new JFrame("");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2000, 1));
for (int i = 0; i != 2000; i++) {
JButton btn = new JButton("Button 2");
panel.add(btn);
}
final JScrollPane sPane = new JScrollPane(panel);
final int increment = 50;
sPane.getVerticalScrollBar().setUnitIncrement(increment);
KeyStroke kUp = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
KeyStroke kDown = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kUp, "actionWhenKeyUp");
sPane.getActionMap().put("actionWhenKeyUp", new AbstractAction("keyUpAction") {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
final JScrollBar bar = sPane.getVerticalScrollBar();
int currentValue = bar.getValue();
bar.setValue(currentValue - increment);
}
});
sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kDown, "actionWhenKeyDown");
sPane.getActionMap().put("actionWhenKeyDown", new AbstractAction("keyDownAction") {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
final JScrollBar bar = sPane.getVerticalScrollBar();
int currentValue = bar.getValue();
bar.setValue(currentValue + increment);
}
});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(sPane);
f.pack();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.setVisible(true);
}
});
}
private JScrollBarUnitIncrement() {
}
}
It is never good to populate such huge no. of rows in JScrollPane. Because, the visible portion is only around let's say 20 to 30 rows in viewport depending on the height of the scrollpane and the height of your RowPanel. So, why to populate such huge rows at once ? The problem with the smoothness is because there might be exception (see the console ). So, resolve this, I see two options for you. One is to use pagination and another is to allow users to enter some search criteria to filter out the unwanted records.
As #mKorbel notes, both JTable and JList implement Scrollable for convenient scroll increments, and they both use the flyweight pattern for rendering speed. If you can't use either component directly, you can still use the patterns. The tutorial includes Scrollable examples, and there's a CellRendererPane example here.
I'm having what I am sure is very much a beginners problem with my JScrollPanes. The problem is that the vertical scrollbar overlaps the components within the enclosed panel (on the right hand side). It becomes a bit of a pain when the scrollbar overlaps the drop-down bit of JComboBoxes.
I have boiled the problem down to this little snippet - I hope it illustrates the issue.
public class ScrollTest extends JFrame
{
public ScrollTest()
{
super("Overlap issues!");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(100,0));
for(int b=0;b<100;++b)
{
panel.add(new JButton("Small overlap here ->"));
}
JScrollPane scrollpane = new JScrollPane(panel);
add(scrollpane);
pack();
setVisible(true);
}
public static void main(String[] args)
{
new ScrollTest();
}
}
I had a look first but couldn't see if anyone else had already addressed this problem. Sorry if it's a duplicate and many thanks for any help anyone can offer a java-newb like me!
The problem is that the default for a JScrollPane is to layout the components with a default of JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED which in turn adds the scrollbar without laying out the components again.
In your example you know you will need a scrollbar so change it to always display the scrollbar
public class ScrollTest extends JFrame
{
public ScrollTest()
{
super("Overlap issues!");
JPanel panel = new JPanel();
//Insets insets = panel.getInsets();
//insets.set(5, 5, 5, 25);
//insets.set(top, left, bottom, right);
panel.setLayout(new GridLayout(100,0));
for(int b=0;b<100;++b)
{
panel.add(new JButton("Small overlap here ->"));
}
JScrollPane scrollpane = new JScrollPane(panel);
scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollpane);
pack();
setVisible(true);
}
public static void main(String[] args)
{
new ScrollTest();
}
}