JScrollPane component change - java

i have a JScrollPane.
But default it displays JTextArea.
JTextArea jTextArea = new JTextArea();
JScrollPane pane = new JScrollPane(jTextArea);
so here everything is fine. But now i would like to change JScrollPane component by user action:
pane.remove(jTextArea);
pane.add(new JTable(data[][], columns[]));
pane.revalidate();
frame.repaint();
frame in my main Window. JScrollPane is added to main window with GridBagLayout.
But this doesn't work. After running action JScrollPane becomes grey.

jScrollPane.getViewport().remove/add

One alternative is to put a JPanel with a CardLayout1 into the JScrollPane, add both the components to the panel, then simply flip between the text area and table as needed.
How to Use CardLayout
Given the components might be of vastly different size, it might be better to do it this way:
JPanel with CardLayout contains many JScrollPane instances, each of which contains a single component. That will also work inherently better for a JTable.

Edited my answer after receiving one valuable suggestion by His Majesty #camickr, setViewportView(componentObject); is used to do such things.
A sample code to help your cause :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ScrollPaneExample extends JFrame
{
private JPanel panel;
private JScrollPane scrollPane;
private JTextArea tarea;
private JTextPane tpane;
private JButton button;
private int count;
public ScrollPaneExample()
{
count = 0;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
panel = new JPanel();
panel.setLayout(new BorderLayout());
tarea = new JTextArea();
tarea.setBackground(Color.BLUE);
tarea.setForeground(Color.WHITE);
tarea.setText("TextArea is working");
scrollPane = new JScrollPane(tarea);
tpane = new JTextPane();
tpane.setText("TextPane is working.");
button = new JButton("Click me to CHANGE COMPONENTS");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (count == 0)
{
scrollPane.setViewportView(tpane);
count++;
}
else if (count == 1)
{
scrollPane.setViewportView(tarea);
count--;
}
}
});
setContentPane(panel);
panel.add(scrollPane, BorderLayout.CENTER);
panel.add(button, BorderLayout.PAGE_END);
pack();
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ScrollPaneExample();
}
});
}
}
Hope this might help you in some way.
Regards

Related

Java Swing Removing Jpanel while clicking on Jbutton which is present in that jpanel which I want to remove

I am creating a GUI using Netbeans and my question is "how to remove the jpanel"...the hierarchical order as it is present Jframe->Jscrollpane->Jpanel->Jbutton. By clicking on the Jbutton I want to remove all components of the jpanel including the Jbutton(on which I am clicking) and the panel itself. Please do help.Urgent.THanks in advance
-Sayantan
private void b4ActionPerformed(java.awt.event.ActionEvent evt) {
final JPanel jp;
JTextField tf,of1,of2,xf,yf;
int i=1;
int m=(int)sp3.getValue();
JButton jb;
jp=new JPanel();
//jp.setLayout(new GridBagLayout());
DesignGridLayout layout = new DesignGridLayout(jp);
jsp2.getViewport().add(jp);
while(i<=m){
tf=new JTextField(5);
of1=new JTextField(5);
of2=new JTextField(5);
layout.row().grid(new JLabel("Type:")).indent(9).add(tf).grid(new JLabel("Length:")).indent().add(of1).grid(new JLabel("Breadth:")).indent().add(of2).empty();
fields1.add(tf);
fields1.add(of1);
fields1.add(of2);
xf=new JTextField(5);
yf=new JTextField(5);
layout.row().grid(new JLabel("X-axis:")).indent(9).add(xf).grid(new JLabel("Y-axis:")).indent().add(yf).empty(2);
fields1.add(xf);
fields1.add(yf);
i++;
}
jb=new JButton("Submit");
jb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
for(JTextField field: fields1){
String s=field.getText();
lbr.setText(lbr.getText()+s);
}
lb3.setVisible(false);
sp3.setVisible(false);
b4.setVisible(false);
//jp.setVisible(false);
//jp.removeAll();
// jp.revalidate();
//jp.repaint();
// jsp2.remove(jp);
//jsp2.revalidate();
//jsp2.repaint();
}
});
layout.emptyRow();
layout.row().right().add(jb);
jp.revalidate();
jp.repaint();
// jsp2.revalidate();
//jsp2.repaint();
}
Note: I am using DesignGridLayout package.
This works:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ScratchSpace {
public static void main(String[] args) {
final JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(Color.YELLOW);
panel.add(new JButton(new AbstractAction("Kill me") {
#Override
public void actionPerformed(ActionEvent e) {
panel.removeAll();
panel.revalidate();
panel.repaint();
}
}));
final JFrame frame = new JFrame();
frame.setContentPane(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
I want to remove all components of the jpanel including the Jbutton(on which I am clicking) and the panel itself.
Then you need code something like:
JButton button = (JButtton)event.getSource();
JPanel grandparent = button.getParent().getParent();
grandparent.removeAll();
grandparent.revalidate();
grandparent.repaint();
Although I question any code where I see a removeAll(). You might look into using a Card Layout.

Adding ScrollPane to JTextArea

I am working on a project for my college course. I was just wondering if anyone knew how to add a scrollBar to a JTextArea. At present I have the GUI laid out correctly, the only thing missing is the scroll bar.
This is what the GUI looks like. As you can see on the second TextArea I would like to add the Scrollbar.
This is my code where I create the pane. But nothing seems to happen... t2 is the JTextArea I want to add it to.
scroll = new JScrollPane(t2);
scroll.setBounds(10,60,780,500);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Any help would be great, thanks!
The Scroll Bar comes when your text goes beyond the bounds of your view area. Don't use Absolute Positioning, for such a small talk at hand, always prefer Layout Managers, do read the first para of the first link, to know the advantage of using a Layout Manager.
What you simply need to do is use this thingy :
JTextArea msgArea = new JTextArea(10, 10);
msgArea.setWrapStyleWord(true);
msgArea.setLineWrap(true);
JScrollPane msgScroller = new JScrollPane();
msgScroller.setBorder(
BorderFactory.createTitledBorder("Messages"));
msgScroller.setViewportView(msgArea);
panelObject.add(msgScroller);
Here is a small program for your understanding :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextAreaScroller
{
private JTextArea msgArea;
private JScrollPane msgScroller;
private JTextArea logArea;
private JScrollPane logScroller;
private JButton sendButton;
private JButton terminateButton;
private Timer timer;
private int counter = 0;
private String[] messages = {
"Hello there\n",
"How you doing ?\n",
"This is a very long text that might won't fit in a single line :-)\n",
"Okay just to occupy more space, it's another line.\n",
"Don't read too much of the messages, instead work on the solution.\n",
"Byee byee :-)\n",
"Cheers\n"
};
private ActionListener timerAction = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter < messages.length)
msgArea.append(messages[counter++]);
else
counter = 0;
}
};
private void displayGUI()
{
JFrame frame = new JFrame("Chat Messenger Dummy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(0, 1, 5, 5));
logArea = new JTextArea(10, 10);
logArea.setWrapStyleWord(true);
logArea.setLineWrap(true);
logScroller = new JScrollPane();
logScroller.setBorder(
BorderFactory.createTitledBorder("Chat Log"));
logScroller.setViewportView(logArea);
msgArea = new JTextArea(10, 10);
msgArea.setWrapStyleWord(true);
msgArea.setLineWrap(true);
msgScroller = new JScrollPane();
msgScroller.setBorder(
BorderFactory.createTitledBorder("Messages"));
msgScroller.setViewportView(msgArea);
centerPanel.add(logScroller);
centerPanel.add(msgScroller);
JPanel bottomPanel = new JPanel();
terminateButton = new JButton("Terminate Session");
terminateButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (timer.isRunning())
timer.stop();
else
timer.start();
}
});
sendButton = new JButton("Send");
bottomPanel.add(terminateButton);
bottomPanel.add(sendButton);
contentPane.add(centerPanel, BorderLayout.CENTER);
contentPane.add(bottomPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new JTextAreaScroller().displayGUI();
}
});
}
}
Here is the outcome of the same :
The scroll bar by default will only be shown when the content overfills the available viewable area
You can change this via the JScrollPane#setVerticalScrollBarPolicy method, passing it ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS

Refresh JTabbedPane component

I am trying to implement JTabbedPane. In the following code I have presented a case very similar to what I want to implement. I have created a tab by adding a JPanel to the JTabbedPane. I have added a JButton and JScrollPane to the JPanel. On click of the JButton I want to add a new JPanel having some JRadioButtons to the JScrollPane. But these are not shown even after refreshing the JScrollPane or main JPanel. Please help. The code is given below.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Test {
static JFrame frame;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
//Create and set up the window.
frame = new JFrame("DynamicTreeDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tp = new JTabbedPane();
final JScrollPane jsp = new JScrollPane();
JPanel jp = new JPanel();
JButton jb = new JButton("Refresh");
jb.setActionCommand("Show");
jb.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equalsIgnoreCase("Show")){
JRadioButton jrb1 = new JRadioButton("First Option");
JRadioButton jrb2 = new JRadioButton("Second Option");
JRadioButton jrb3 = new JRadioButton("Third Option");
ButtonGroup bg = new ButtonGroup();
bg.add(jrb1);
bg.add(jrb2);
bg.add(jrb3);
JPanel p = new JPanel(new GridLayout(0,1));
p.add(jrb1);
p.add(jrb2);
p.add(jrb3);
jsp.add(p);
jsp.revalidate();
jsp.repaint();
}
}
});
jp.setLayout(new GridLayout(0,1));
jp.add(jb);
jp.add(jsp);
tp.add("First Tab", jp);
frame.getContentPane().add(tp);
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
To add something to JScrollPane use its JViewport rather than directly calling add(). In your example replace:
jsp.add(p);
with:
jsp.getViewport().add(p);
Alternatively, initialize JScrollPane with a JPanel that holds other components. Based on your example:
final JPanel panel = new JPanel();
final JScrollPane jsp = new JScrollPane(panel);
panel.add(new JRadioButton("First Option"));
panel.add(new JRadioButton("Second Option"));
panel.add(new JRadioButton("Third Option"));
See How to Use Scroll Panes for more details.
The components should be added to the JPanel called jp rather than directly to the scroll pane.
JScrollPane only works with a single "View". You cannot add components to the scrollPane. If you want, you can change the "View" using setViewPortView(). To achieve the behaviour you are looking for, do the following:
JPanel centralView = new JPanel();
// possibly configure that central view with appropriate layout and other stuffs
JScrollPane jsp = new JScrollPane(centralView);
...
// Now you can add your components to centralView instead of your jsp.add(...) calls.
You should add the JPanel to the JScollPanes viewport using getViewport(), then repack the JFrame to get the sizing issue sorted using pack();:
jsp.getViewport().add(p);
frame.pack();
instead of:
jsp.add(p);
jsp.revalidate();
jsp.repaint();

JScrollPane won't work

Hey guys I wanted to create a JScrollPane but it won't work... and I don't know why... here's my code...
public class test extends JFrame{
public test(){
setSize(1000,600);
}
private static JButton[] remove;
private static JPanel p = new JPanel();
public static void main(String[]args){
p.setLayout(null);
JFrame t=new test();
remove = new JButton[25];
for(int i=0;i<25;i++){
remove[i]=new JButton("Remove");
remove[i].setBounds(243,92+35*i,85,25);
p.add(remove[i]);
}
JScrollPane scrollPane = new JScrollPane(p);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
t.add(scrollPane);
t.setVisible(true);
}
Umm and Im pretty sure the frame isn't big enough for these 25 buttons... But if i delete that p.setLayout(null); A horizontal scroll bar will be created automatically... I don't really know what is wrong with my code... Pls help thank you very much!
You need to set p's preferredSize for this to work.
p.setPreferredSize(new Dimension(800, 2000));
Or you could have p extend JPanel and then override the getPreferredSize() method to return the proper dimension.
And I agree -- get rid of your null layouts. Learn about and use the layout managers if you want to use Swing correctly and have robust Swing GUI's.
e.g.,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Foo extends JFrame {
private static final int BUTTON_COUNT = 25;
public static void main(String[] args) {
JPanel btnPanel = new JPanel(new GridLayout(0, 1, 0, 20));
btnPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
AbstractAction removeAction = new AbstractAction("Remove") {
#Override
public void actionPerformed(ActionEvent evt) {
JButton src = (JButton) evt.getSource();
JPanel container = (JPanel) src.getParent();
container.remove(src);
container.revalidate();
container.repaint();
}
};
for (int i = 0; i < BUTTON_COUNT; i++) {
JButton removeBtn = new JButton(removeAction);
btnPanel.add(removeBtn);
}
JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.add(btnPanel, BorderLayout.NORTH);
JScrollPane scrollpane = new JScrollPane(borderPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollpane.setPreferredSize(new Dimension(400, 800));
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(scrollpane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
The issue is that a scroll pane checks the component inside it for a "preferred size" so a pane with a null layout has a preferred size of (0,0). Which it ignores.
You should do something along the lines of:
p.setPreferredSize(1000,600);
And you should see some scroll bars appear, I'm not sure how accurate they will be though.

JTabbedPane JLabel, JTextField

Right, I have a JTabbedPane that has a JPanel that contains a JLabel and a JTextField.
my code
JTabbed Pane declaration :
this.tabPane = new JTabbedPane();
this.tabPane.setSize(750, 50);
this.tabPane.setLocation(10, 10);
tabPane.setSize(750,450);
tabPane.add("ControlPanel",controlPanel);
textfield declaration :
this.channelTxtFld = new JTextField("");
this.channelTxtFld.setFont(this.indentedFont);
this.channelTxtFld.setSize(200, 30);
this.channelTxtFld.setLocation(200, 10);
JLabel :
this.channelLabel = new JLabel("Channel name : ");
this.channelLabel.setSize(150, 30);
this.channelLabel.setLocation(10,10);
private void createPanels() {
controlPanel = new JPanel();
controlPanel.setSize(650,500);
}
private void fillPanels() {
controlPanel.add(channelLabel);
controlPanel.add(channelTxtFld);
}
So what my plan is, was to have a tabbed pane that has a JPanel where I have some Labels, textfields and buttons on fixed positions, but after doing this this is my result:
http://i.stack.imgur.com/vXa68.png
What I wanted was that I had the JLabel and next to it a full grown JTextfield on the left side not in the middle.
Anyone any idea what my mistake is ?
thank you :)
What kind of Layout Manager are you using for your controlPanel, you probably want BorderLayout, putting the Label in the West, and the TextField in the center.
BTW, setting the size and position of various components doesn't make sense unless you are using a Null Layout, which isn't a good idea. So i'd remove all that stuff and let the Layout Manager do it for you.
Use a LayoutManager and consider also the methods setPreferredSize, setMinimumSize, setMaximumSize to adjust components bounds according on which is your desired effect.
Assuming the default JPanel layout, FlowLayout, give the JTextField a non-zero number of columns, and give the JLabel a JLabel.LEFT constraint.
Addendum:
a full grown JTextField
Something like this?
import java.awt.*;
import javax.swing.*;
/**
* #see http://stackoverflow.com/questions/5773874
*/
public class JTabbedText {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
private final JTabbedPane jtp = new JTabbedPane();
#Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtp.setPreferredSize(new Dimension(400, 200));
jtp.addTab("Control", new MyPanel("Channel"));
f.add(jtp, BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}
private static class MyPanel extends JPanel {
private final JLabel label = new JLabel("", JLabel.LEFT);
private final JTextField text = new JTextField();
public MyPanel(String name) {
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
label.setText(name);
label.setAlignmentY(JLabel.TOP_ALIGNMENT);
text.setAlignmentY(JTextField.TOP_ALIGNMENT);
this.add(label);
this.add(text);
}
}
}

Categories