Java Fitting JPanel into Modal JDialog - java

I have a class that returns a JPanel:
public static JPanel program(String csvName) {
JPanel f = new JPanel();
try {
String path = System.getProperty("user.dir");
String datafile = path+"/files/logic/"+csvName+".csv";
FileReader fin = new FileReader(datafile);
DefaultTableModel m = createTableModel(fin, null);
JTable table = new JTable(m);
JScrollPane stable = new JScrollPane (table);
stable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
stable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
f.add(stable);
f.setMinimumSize(new Dimension(900,500));
JFrame desktopFrame = new JFrame();
desktopFrame.add(f);
desktopFrame.setSize(900, 500);
desktopFrame.setVisible(true);
toExcel(m, new File(path+"/files/logic/"+csvName+".csv"));
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
And this is what is used to display the JPanel Modally.
String csv = "war";
JPanel f = T1Data.program(csv);
JDialog desktopFrame = new JDialog();
desktopFrame.add(f);
desktopFrame.setModal(true);
desktopFrame.setSize(900, 500);
desktopFrame.setVisible(true);
However the result I am getting has the JPanel centered and not fitting the JDialog.
It looks like this:
http://gyazo.com/4bc360e7d2c7cf7117a95d748d520838.png
How can I fix this?

The JPanel is using a FlowLayout, if you change it to a BorderLayout, the scroll panel will be laid out so it fills the full container.
You should also consider using JDialog#pack over setSize as well

To make the panel fit the size of the dialog, you can either change the LayoutManager of the dialog, or ,since this should obviously be the only panel added to the dialog, simply set the panel as contentpane (desktopFrame.setContentPane(f) instead of desktopFrame.add(f)).

Related

Java Swing JTabbedPane layout

I am new to Swing and cannot find a page that helps me understand JTabbedPane. I cannot find a way to control the layout of components of the tabbed panels. I can layout each of my panels correctly as separate GUIs but not in a tabbed pane like I need to do. I would like to use the BorderLayout not FlowLayout.
Also, you can see I'm trying to use colors to keep track of my panels and their components. I cannot set the background of the JTabbedPane. It is still the default grey. Can someone tell me why this is?
Thank you for any advice you can give.
What I have so far appears to follow a 'flow layout' despite any changes I've tried
(Methods have been removed or nearly removed to keep code shorter)
public class GUIFrame extends JFrame {
public GUIFrame(String title) {
JFrame frame = new JFrame(title);
Container c = frame.getContentPane();
buildGUI(c);
setFrameAttributes(frame);
}
private void buildGUI(Container c) {
c.setLayout(new BorderLayout());
c.setBackground(Color.BLACK);
JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
tabs.setBackground(Color.YELLOW);
c.add("Center", tabs);
tabs.addTab("Specialty", new SpecialtyPanel());
tabs.addTab("Treatment", new TreatmentPanel());
tabs.addTab("Doctor", new DoctorPanel());
tabs.addTab("Patient", new PatientPanel());
}
private void setFrameAttributes(JFrame f) {
f.setSize(500, 500);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
MedicalSystemIO test = new MedicalSystemIO();
new GUIFrame("Tabbed Title");
}
public class SpecialtyPanel extends JPanel implements ActionListener {
JTextField jteInput = null;
DefaultListModel<String> model = new DefaultListModel<String>();
JList<String> list = new JList(model);
JScrollPane pane = new JScrollPane(list);
public SpecialtyPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.black));
buildGUI(panel);
}
private void buildGUI(JPanel panel) {
JPanel jpaInput = createInputPanel();
JPanel jpaProcess = createProcessPanel();
JPanel jpaOutput = createOutputPanel();
//panel.setLayout(new BorderLayout());
add("North", jpaInput);
add("Center", jpaProcess);
add("South", jpaOutput);
}
private JPanel createInputPanel() {
JPanel jpaInput = new JPanel();
jpaInput.setBackground(Color.RED);
return jpaInput;
}
private JPanel createProcessPanel() {
JPanel jpaProcess = new JPanel();
jpaProcess.setBackground(Color.BLUE);
return jpaProcess;
}
private JPanel createOutputPanel() {
JPanel jpaOutput = new JPanel();
jpaOutput.add(pane);
return jpaOutput;
}
The SpecialtyPanel is shown that way (flow layout) as you are putting the components on it in the wrong way:
No need for passing a new panel into the buildGUI method as you want to put them directly on the SpecialtyPanel which already is a JPanel,
you commented out the setting of the BorderLayout and
you used the wrong notation of passing the layout constraints in the add methods.
Your constructor and build method should look like this:
public SpecialtyPanel() {
buildGUI();
}
private void buildGUI() {
setBorder(BorderFactory.createLineBorder(Color.black));
JPanel jpaInput = createInputPanel();
JPanel jpaProcess = createProcessPanel();
JPanel jpaOutput = createOutputPanel();
setLayout(new BorderLayout());
add(jpaInput, BorderLayout.NORTH);
add(jpaProcess, BorderLayout.CENTER);
add(jpaOutput, BorderLayout.SOUTH);
}
To have the panel another color than gray you have to color the component that is put on the tabbed pane as it covers the whole space. Add the desired color to the buildGUI method, e.g.:
private void buildGUI(JPanel panel) {
// ...
setBackground(Color.YELLOW);
}
As a JPanel is opaque by default (that means not transparent), you need to set panels on top (except those which you colored explicitly) to be transparent. In case of SpecialtyPanel:
private JPanel createOutputPanel() {
JPanel jpaOutput = new JPanel();
jpaOutput.add(pane);
jpaOutput.setOpaque(false); // panel transparent
return jpaOutput;
}

JScrollPane doesn't work while inside a JPanel

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.

Struggling with the append method for JTextArea

This is the code I am struggling with. It is refusing to amend the JTextArea with the new text. I create the window and set it to visible in the main function of the project.
Thanks ahead.
EDIT:
By refusing, I mean the JTextArea will simply not display the text. It just stays empty. I'm not getting and error or exception. It is all logical.
class Window extends JFrame{
protected JTextArea text;
public Window() {
setTitle("Create a list of names");
setSize(500,400);
Container containerPane = getContentPane();
JPanel jp = new JPanel();
text = new JTextArea(10,50);
text.setPreferredSize(new Dimension(256,256) );
text.setEditable(false);
JScrollPane scrollText = new JScrollPane(text);
scrollText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jp.add(scrollText);
containerPane.add(jp, BorderLayout.CENTER);
text.append("Test");
}
public static void main(String[] args) {
Window w = new Window();
w.setVisible(true);
}
}
The column width of 50 is greater than the width of the frame so the added text appears offscreen. Reduce its value to fit the parent window
textArea = new JTextArea(10, 35);
Don't use setPrerredSize. Let the layout manager do its job and call pack after all components have been added.

How do I resize JScrollPane after resizing a JTextArea

My JFrame Consists of three main parts a banner at top scrollpane containing a JTextArea center and a JTextField at the bottom. When I re-size the frame I adjust the columns and rows in my JTextArea. When making the frame larger the JTextArea expands visually but removes the scroll-bar. Then if I make the frame smaller the JTextArea stays the same size. This Is where I attempt to re-size my JTextArea.
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
Why would the ScrollPane not re adjust to the change in size of the TextField.
The Rest of the code is below in case it is needed.
public class window extends JFrame
{
private static JFrame frame = new JFrame("Lillian");
private static JButton inputButton = new JButton("Send");
private static JTextField editTextArea = new JTextField(46);
private static JTextArea uneditTextArea = new JTextArea(26,50);
private static JPanel logoPanel = new JPanel();//Input text window
private static JPanel itextPanel = new JPanel();//Input text window
private static JPanel submitPanel = new JPanel();//Submit Button
private static JPanel bottom = new JPanel();//will contain scrollpane
private static JPanel middle = new JPanel();//willcontain itextpanel & submitbutton
private static JPanel otextPanel = new JPanel();//Text Output
public static void runWindow()
{
ImageIcon logo = new ImageIcon("Lillian_resize.png");//banner
ImageIcon icon = new ImageIcon("Lillian_icon.png");//application icon
frame.setIconImage(icon.getImage());
frame.setSize(660,640);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
logoPanel.setSize(10,10);
JLabel logoLabel = new JLabel(logo);
final JScrollPane scrollPane = new JScrollPane(otextPanel);//adds text to panel will scrollbar
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);//scrollbar only apears when more text than screen
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);//scrollbar never apears
scrollPane.setBorder(BorderFactory.createEmptyBorder());
logoPanel.add(logoLabel);
submitPanel.add(inputButton);
itextPanel.add(editTextArea);
otextPanel.add(uneditTextArea);
frame.getContentPane().add(logoPanel,"North");
frame.getContentPane().add(middle);
frame.getContentPane().add(bottom,"South");
middle.add(scrollPane,"North");//adds panels to outer panel
bottom.add(itextPanel, "West");
bottom.add(submitPanel, "East");
uneditTextArea.setLineWrap(true);
uneditTextArea.setWrapStyleWord(true);
uneditTextArea.setEditable(false);
uneditTextArea.setCaretPosition(uneditTextArea.getDocument().getLength());
frame.revalidate();//refreshes screen
//---------------wait for action------------
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
}
}
There should be no need to use a ComponentListener to resize components. That is the job of the layout managers that you use to dynamically resize the components.
You should not be adding the text area to a JPanel first. Instead when using text areas you would generally add the text area directly to the viewport of a JScrollPane by using code like:
JScrollPane scrollPane = new JScrollPane( textArea );
Then you add the scrollpane to the frame with code like:
frame.add(scrollPane, BorderLayout.CENTER);
As you have noticed you should also NOT use hardcoded literals like "Center". Instead use the variables provided by the layout manager. Since you are using a BorderLayout, use the variables defined in the BorderLayout class.
Also, you should NOT be using static variable to create your GUI. I suggest you read the section from the Swing tutorial on Layout Manager. The tutorial will give you more information and the example code will show you how to better structure your program so that you don't need to use static variables.

JTextField not appearing on top of JFrame

How do I get a textbox to appear on this JFrame? Also is it good practice to build everything on top of the JFrame itself? Or is it better to overlay a JPanel and build everything on top of that?
Thanks in advance!
public class GUI {
private static JFrame frame = new JFrame("FrameDemo");
public GUI() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage myImage = null;
try {
myImage = ImageIO.read(new File("C:/Users/Desktop/background.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frame.setContentPane(new ImageFrame(myImage));
JTextField field = new JTextField(10);
frame.add(field, BorderLayout.SOUTH);
Dimension dimension = new Dimension();
dimension.setSize(950, 800);
frame.setSize(dimension);
frame.setVisible(true);
}
}
You have replaced the default content pane with you own content pane. I would guess your content pane does not use a layout manager so the text field is never displayed.
Try something like:
//frame.setContentPane(new ImageFrame(myImage));
ImageFrame content = new ImageFrame(myImage));
content.setLayout( new BorderLayout() );
frame.setContentPane(content);
Now you text field should be added to the south of your image panel.
Also is it good practice to build everything on top of the JFrame itself? Or is it better to overlay a JPanel and build everything on top of that?
The content pane of a JFrame is a JPanel, so it doesn't really matter what you do since your will be using a panel either way. The key is to manage the layout manager of your content pane.

Categories

Resources