[Thanks for the answers. This comes for you http://www.youtube.com/watch?v=Vo0Cazxj_yc ]
This might and should be a very easy question, but i could not find a solution.
I have a java applet, and i want a vertical scrollbar so that i can load thousands of buttons into the applet and use the scrollbar to see buttons down on the applet.
Buttons are used to select items. if button is pressed, the item is selected.
When i load buttons, all of them are shown on one screen, squeezed together to fit the screen in width and height (~1000px,~1000px). Below code is a portion of my program. Please comment.
JFrame frame = new JFrame();
NameClassifier nameClassifier = new NameClassifier();
JScrollPane scrollPane = new JScrollPane(nameClassifier);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(scrollPane);
frame.getContentPane().add(nameClassifier);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.println("exiting");
import java.awt.*;
import javax.swing.*;
class ManyButtons {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
NameClassifier nameClassifier = new NameClassifier();
JScrollPane scrollPane = new JScrollPane(nameClassifier);
scrollPane.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(scrollPane);
// nameClassifier has already been added to the scroll pane.
//frame.getContentPane().add(nameClassifier);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.println("exiting");
}
});
}
}
class NameClassifier extends JPanel {
NameClassifier() {
super(new GridLayout(0,10,2,2));
for (int ii=1; ii<=1000; ii++) {
add(new JButton("Button " + ii));
}
}
}
I think you want to use a Wrap Layout.
Don't add anything directly to the frame, so
frame.add(scrollPane);
is wrong.
Add things to the content pane. probably
scrollPane.add(nameClassifier);
frame.getContentPane().add(scrollPane);
btw, that is one pretty gui design. :)
Related
JScrollPane works perfectly when I give it a JPanel and then add the JScrollPane directly on to a JFrame with frame.getContentPane.add(). However, it doesn't work when I add the JScrollPane to a JPanel and then add the JPanel to the JFrame. I need to use the second method because I'm going to add multiple things inside the JPanel and JFrame and I need to keep it organized. Here is my code.
import java.awt.*;
import javax.swing.*;
public class Main {
/**
* #param inpanel asks if the JScrollPane should
* be inside of a JPanel (so other things can also be added)
*/
public static void testScroll(boolean inpanel) {
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
f.setResizable(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.red));
//panel.setLayout(new BoxLayout(panel, 1));
panel.setLayout(new GridLayout(0,1));
for (int i = 0; i < 100; i++) {
JLabel l = new JLabel("hey"+i,SwingConstants.CENTER);
l.setBorder(BorderFactory.createLineBorder(Color.green));
l.setPreferredSize(new Dimension(200,200));
panel.add(l);
}
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setBorder(BorderFactory.createLineBorder(Color.blue));
//**********THIS DOES NOT WORK HOW I WANT IT TO************
if(inpanel){
JPanel holder = new JPanel();
holder.add(scrollPane);
f.getContentPane().add(holder);
}
//************THIS DOES WORK HOW I WANT IT TO****************
else{
f.getContentPane().add(scrollPane);
}
f.pack();
f.setSize(500, 500);
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMaximum());
bar.setUnitIncrement(50);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
testScroll(false); //OR TRUE
}
};
SwingUtilities.invokeLater(r);
}
}
In the main method, if I pass false, it works like I mentioned before, but when I pass true it shows up without a scroll bar.
Picture when passing false
Picture when passing true
I need a way to add the JScrollPane to a JPanel and still have it work.
Thanks in advance!
Your problem is the holder JPanel's layout. By default it is FlowLayout which will not re-size its child components when need be. Make it a BorderLayout instead, and your scrollpane will resize when needed. If you need something more complex, check out the layout manager tutorials.
I am trying to get a JInternalFrame to appear on my screen when a button is pressed, a pop up effect basically. However when the button is pressed the JInternalFrame does not appear on the screen. Also when I resize the screen all the elements expand with it, I am wondering if there is a way to get a pop up window to appear on the screen and keep the layout manager I have now still in place so that when the window is resized the elements are also resized with it
public class testing2 implements ActionListener {
JButton buttonAppear = new JButton();
JLayeredPane LayeredPane = new JLayeredPane();
public static void main(String[] args) {
new testing2();
}
public testing2() {
LayeredPane = new JLayeredPane();
BorderLayout borderlayoutpane = new BorderLayout();
LayeredPane.setLayout(borderlayoutpane);
JPanel mainPanel = new JPanel();
BorderLayout borderlayout = new BorderLayout();
mainPanel.setLayout(borderlayout);
JButton button = new JButton("Button");
mainPanel.add(button, "Center");
buttonAppear = new JButton("Panel Appear");
buttonAppear.addActionListener(this);
mainPanel.add(buttonAppear, "South");
LayeredPane.add(mainPanel, 2);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(LayeredPane);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == buttonAppear)
{
JInternalFrame inFrame = new JInternalFrame("Internal Frame", true, true, true, true);
inFrame.setBounds(10, 10, 200, 200);
inFrame.setVisible(true);
LayeredPane.add(inFrame, 1);
}
}
}
a pop up effect basically.
Then use a JDialog. A JInternalFrame was designed to work with a JDesktopPane.
mainPanel.add(button, "Center");
Don't use hardcode strings for the constraint. Use the field provided by the API:
mainPanel.add(button, BorderLayout.CENTER);
Also, follow Java naming conventions. Variable names should NOT start with an upper case character. Be consistent.
Don't know if it will make a difference but components with a higher layer number are painted on top of components with a lower index. So I would guess the panel (which is opaque) would just paint over top of the internal frame. Read the section from the Swing tutorial on How to Use Layered Panes. Also read the section on How to Use Root Panes to find the special variable for "popups" on a layered pane.
Check out if you can help on this.
I need to restrict the scrolling to only vertical when using JScrollPane.
REMEMBER: not disabling the hortizontal scroll bar by using HORIZONTAL_SCROLLBAR_NEVER, which just disable horizontal. And i need is the components should not go beyond the window horizontally.
Add this to the container within the JScrollPane:
#Override
public java.awt.Dimension getPreferredSize() {
int h = super.getPreferredSize().height;
int w = getParent().getSize().width;
return new java.awt.Dimension(w, h);
}
At first I suggest you to check this out.
http://www.java-tips.org/java-se-tips/javax.swing/how-to-use-a-scrollbar-in-both-vertical-and-horizontal-dire.html
and you can actually try these lines of codes as well:
public class AddScroll
{
public static void main(String[] args)
{
JPanel panel = new JPanel();
JScrollPane scrollBar = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JFrame frame = new JFrame("AddScrollBarToJFrame");
frame.add(scrollBar);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
I've been spending some time relearning java and a peculiar logic error hit me here.
import javax.swing.*;
import java.awt.*;
class Frame
{
public static void main (String args[])
{
JFrame frame = new JFrame("Tester Frame");
frame.setSize(400, 500);
JButton btn1 = new JButton("FOO");
btn1.setSize(150, 50);
btn1.setLocation(45, 0);
JButton btn2 = new JButton("BAR");
btn2.setSize(150, 50);
btn2.setLocation(205, 0);
Container content = frame.getContentPane();
content.setBackground(Color.blue);
content.add(btn1);
content.add(btn2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}//end main
}
I've created 2 JButton objects, and they should be the same size, with different location and text. This of course is not the case, the "FOO" button is exactly where and how I want it to be, but the "BAR" button is the size of the entire frame.
Help!
1) You are attempting to use Absolute LayoutManager via setSize and setLocation etc, but without calling setLayout(null) on the component you are adding the JButtons to. However this is not a best practice in Swing.
When adding to JFrame contentpane default layout is BorderLayout which adds components to is default position of BorderLayout.CENTER.
Have a read on A Visual Guide to Layout Managers
2) Also when using a correct LayoutManager you would omit JFrame#setSize(..) call and replace it with JFrame#pack() before setting the JFrame visible.
3) Also have a read on Concurrency in Swing specifically on The Event Dispatch Thread
which dictates all swing components be created on EDT via SwingUtillities.invokeXXX(..) block:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//create and manipulate swing components here
}
});
4) Also rather use JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); as this will allow any other threads timers etc to carry on execution even after JFrame has been disposed.
add:
frame.getContentPane().setLayout(null);
To your code after the line:
frame.setSize(400, 500);
Components added to a container are tracked in a list. The order of the list will define the components' front-to-back stacking order within the container. If no index is specified when adding a component to a container, it will be added to the end of the list (and hence to the bottom of the stacking order).In your code the buttons are stacked over the other.That is why you get this Error(as you think it is).
This will solve your problem:-
import javax.swing.*;
import java.awt.*;
class OP3
{
public static void main (String args[])
{
JFrame frame = new JFrame("Tester Frame");
frame.setSize(400, 500);
JButton btn1 = new JButton("FOO");
btn1.setSize(150, 50);
btn1.setLocation(45, 0);
JButton btn2 = new JButton("BAR");
btn2.setSize(150, 50);
btn2.setLocation(205, 0);
JPanel p = new JPanel(new FlowLayout());
p.add(btn1);
p.add(btn2);
frame.add(p);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}//end main
}
Just add a panel to the frame and add the buttons to the panel.
import javax.swing.*;
import java.awt.*;
class source
{
public static void main (String args[])
{
JFrame frame = new JFrame("Tester Frame");
frame.setSize(400, 500);
JPanel panel=new JPanel();//panel added here
panel.setSize(frame.size());
panel.setLocation(0, 0);
JButton btn1 = new JButton("FOO");
btn1.setSize(150, 50);
btn1.setLocation(45, 0);
JButton btn2 = new JButton("BAR");
btn2.setSize(150, 50);
btn2.setLocation(205, 0);
panel.add(btn1);
panel.add(btn2);
Container content = frame.getContentPane();
content.setBackground(Color.blue);
content.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}//endmain
I am trying to put a text area onto a dialog box using Java Swing. I have a problem of setting the size of this JTextArea. The width of the text area is always equal to the whole width of the window and stretches with the window if I resize it.
private void arrangeComponents() {
JTextArea textArea = new JTextArea();
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(textArea);
outerPanel.add(scrollPane, BorderLayout.CENTER);
Container contentPane = getContentPane();
contentPane.add(outerPanel, BorderLayout.CENTER);
}
I want the JTextArea to be horizontally aligned to the centre of the window and does not change its size.
What did I do wrong?
Use the JTextArea(int rows, int columns) constructor that specifies rows and columns, as shown here, and don't neglect to pack() the enclosing Window.
outerPanel.add(scrollPane, BorderLayout.CENTER);
A BoxLayout doesn't take constraints, so the BorderLayout.CENTER is unnecessary.
The problem is that a BoxLayout respects the maximum size of the component which for a scrollpane is set very large.
Instead of using a BoxLayout, just use a panel with a FlowLayout.
Run the example below to see what you are currently doing. Then comment out the setLayout(...) statement and run again. By default the panel uses a FlowLayout so you will get what you want.
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
setLayout( new BoxLayout(this, BoxLayout.PAGE_AXIS));
JTextArea textArea = new JTextArea(5, 30);
JScrollPane scrollPane = new JScrollPane(textArea);
//scrollPane.setMaximumSize( scrollPane.getPreferredSize() );
add(scrollPane);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SSCCE() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Or if you really want to keep the BoxLayout then leave keep the setLayout(...) statement and then set the maximum size equal to the preffered size. Many people will say you should never invoke a "setXXX()" method directly and instead you should override the setMaximumSize() method of the scrollpane to just return the preferred size.
Note, when testing these two solutions make sure you make the window smaller than the scrollpane to see how each layout works differently.
i found this from a simple coding site. This code sample may be useful for you.
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class JTextAreaTest {
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("JTextArea Test");
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String text = "A JTextArea object represents a multiline area for displaying text. "
+ "You can change the number of lines that can be displayed at a time, "
+ "as well as the number of columns. You can wrap lines and words too. "
+ "You can also put your JTextArea in a JScrollPane to make it scrollable.";
JTextArea textAreal = new JTextArea(text, 5, 10);
textAreal.setPreferredSize(new Dimension(100, 100));
JTextArea textArea2 = new JTextArea(text, 5, 10);
textArea2.setPreferredSize(new Dimension(100, 100));
JScrollPane scrollPane = new JScrollPane(textArea2,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
textAreal.setLineWrap(true);
textArea2.setLineWrap(true);
frame.add(textAreal);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
}
Just call that method for ur text area: setLineWrap(true);
If JTextArea is initializated
JTextArea text = new JTextArea(int rows, int columns)
you just call the method text.setLineWrap(true)
then text'size is fixed.