Results 1 to 14 of 14

Thread: JTabbedPanes

  1. #1
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Unhappy JTabbedPanes

    So I've been trying to create a nice little GUI for an application I am working on. My initial way of creating this TabbedPane was to have an array for all of my components, for example, I knew every pane would need a JTextArea. So I would create an array of JTextArea[]. The problem is I really don't want to keep track of these arrays now. I would like to just keep track of the components based on the name of the Panel they are in.

    Let me go ahead and show you the code, so you can see what is going on. I'll remove the Imports as I do them individually (Eclipse rather...) and there are a lot.

    Java Code:
    public class TabbedPanes extends JPanel {
    	private static final long serialVersionUID = 1L;
        static JTabbedPane tabbedPane = new JTabbedPane(); 
    	Timer swingTimer = new Timer(80, new TimerAction());
    	private static int inc=0;
    
    	public TabbedPanes() {
            Dimension d = new Dimension(300,400);
        	JComponent panels;
    
            for(int i=0;i<5; i++){
            	panels = makeTextPanel("Panel #"+i);
            	panels.setPreferredSize(d);
            	tabbedPane.addTab("Tab "+i, null, panels, "Cool");
            	tabbedPane.setMnemonicAt(i, KeyEvent.VK_0);
            }
            tabbedPane.setTitleAt(0, "General");
            tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
            mainPanel.add(tabbedPane);
            swingTimer.start();
        }
        
        protected JComponent makeTextPanel(String text) {
            Dimension i = new Dimension(280,280);
            Dimension o = new Dimension(280,100);
            JPanel panel = new JPanel(false);
        	JTextArea incomingArea;
        	JTextArea outgoingArea;
        	JScrollPane scrollPane;
        	JScrollPane outgoingPane;
        	JButton test;
         
            incomingArea = new JTextArea(4,20);
            outgoingArea = new JTextArea(4,20);
            
    		incomingArea.setLineWrap(true);incomingArea.setWrapStyleWord(true); incomingArea.setName("Incoming"); 
            incomingArea.setEditable(false); incomingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setWrapStyleWord(true); outgoingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setLineWrap(true); outgoingArea.setName("Outgoing");
     
            outgoingPane = new JScrollPane(outgoingArea); incomingArea.setName("lawl");
    		scrollPane = new JScrollPane(); scrollPane.setName("Incoming"); outgoingPane.setName("Outgoing");
    		scrollPane.setPreferredSize(i); outgoingPane.setPreferredSize(o);
            panel.setName("A new Panel");
            test = new JButton("Send");
            scrollPane.add(new JTextArea(4,20)); outgoingPane.add(outgoingArea);
            panel.add(scrollPane); 		// Component 0
            panel.add(outgoingPane); 	// Component 1
            panel.add(test); 			// Component 2
            inc++;
            return panel;
        }
        public static void myPaint(Graphics g){
    
        }
    	private class TimerAction implements ActionListener {
    		// the swingTimer will call this method every TIMER_DELAY mSecs
    		public void actionPerformed(ActionEvent arg0) {
    			JPanel j = (JPanel) tabbedPane.getComponentAt(0);
    			JScrollPane inc = (JScrollPane) j.getComponent(0);
    			JTextArea i = (JTextArea) inc.getComponent(3);
    			i.append("Lawl it worked..asdf haskdjfh alskjdfh laksjdhfkl ajsdhfl kasjdhfk ajsdhfkl ajsdhfkl ajsdhf klajsdhfk aljsdhf ");
    			mainPanel.repaint();
    		}
    	}
    	public static JPanel mainPanel = new JPanel() {
    		private static final long serialVersionUID = 1L;
    		protected void paintComponent(Graphics g) {
    			super.paintComponent(g);
    			myPaint(g);
    		}
    	};
    	
    	public Component getJPanel(){
    		return mainPanel;
    	}
    
        private static void createAndShowGUI() {
            JFrame frame = new JFrame("BChat Messenger");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new TabbedPanes().getJPanel(), BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
    		UIManager.put("swing.boldMetal", Boolean.FALSE);
    		createAndShowGUI();
                }
            });
        }
    }
    So what I am exactly doing here is creating a tabbedPane. I create individual tabs and then attach them to my tabbedPane and once I've finished adding all individual tabs, I add my tabbedPane to my mainPanel.

    Now that I have this done, It will be necessary for me to get information and give information to the components in each of these tabs. So I've devised a way to do that. If you look inside my timer method, you'll see I use a series of casting/creating of dummy Components that correspond to the components I'm grabbing out of the Panels.

    For example, I know the first component added to tabbedPanes is a JPanel (a tab). And inside that JPanel I know the first component added to it is a JScrollPane. Inside the JScrollPane I know the last component added to it is my JTextArea.

    Now I can confirm all of this by giving them fake names and printing them out. This works fine and dandy. But one thing I've noticed is none of the settings I've given each of my components are actually set. So my outgoingArea is NOT EDITABLe etc.

    Also the biggest test is that when i do "i.append("whatever");" in the Timer, it never updates or displays to the screen. I've used many validates()/revalidates() etc and cannot seem to get this updated.

    Honestly I'm completely lost on this bug. Any one have any thoughts? Or a better suggestion on how to go about doing this? I want to stay away from keeping track of the components in an array style. As I will be add/removing tabs frequently in my application.

    Thanks

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    1) Get rid of all the static methods and variables in your code except for the main and createAndShowGUI methods. This really is against all tenants of OOPs programming.
    2) You appear to be adding your incoming and outgoing text areas to multiple containers, and since the component will only be visible on the last component it was added to, it will be invisible elsewhere. Add a component to only one other container.
    3) To associate a JPanel and its components with a tab, use OOPs techniques. Create a class for the JPanels then add them to the tab. You may need to use a HashMap to get the component out.
    4) Don't forget to use layout managers here (and not the default FlowLayout unless it is the bet for the job).

  3. #3
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    For instance, the TabPanel could have methods similar to the ones shown in this interface:
    Java Code:
    import java.awt.event.*;
    import javax.swing.*;
    
    public interface TabPanelable {
    
      public abstract int getPanelNumber();
    
      public abstract void setPanelNumber(int i);
    
      public abstract void appendIncomingAreaText(String text);
    
      public abstract String getOutGoingAreaText();
    
      public abstract void setOutGoingAreaText(String text);
    
      public abstract void addSendActionListener(ActionListener al);
    
      public abstract JPanel getMainPanel();
    
    }

  4. #4
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    Quote Originally Posted by Fubarable View Post
    1) Get rid of all the static methods and variables in your code except for the main and createAndShowGUI methods. This really is against all tenants of OOPs programming.
    2) You appear to be adding your incoming and outgoing text areas to multiple containers, and since the component will only be visible on the last component it was added to, it will be invisible elsewhere. Add a component to only one other container.
    3) To associate a JPanel and its components with a tab, use OOPs techniques. Create a class for the JPanels then add them to the tab. You may need to use a HashMap to get the component out.
    4) Don't forget to use layout managers here (and not the default FlowLayout unless it is the bet for the job).
    Hey Fubarable. You've helped me a lot so I respect all your suggestions.

    I've removed the static methods and variables as suggested by 1.)

    2.) I'm a little confused by this one. I understand what you are saying. As I re-evaluated my code though, I found that the TextAreas don't need to be added to any Component. They are merely needed by the ScrollPane to display the text. So I am setting the ScrollPane's ViewportView to the TextAreas. Now the question is, do I need to add these textAreas to the panel as well, and make them visible(false) so I keep them?

    3.) Why create a class for this instead of just using the method I've already got? I can't imagine doing anything different with a class. I'd create a class, and a constructor, pass the same variables into the constructor as the method, and be returning a JPanel still right?

    4.) The current layout looks good on my screen and I'd like to stay with it unless you see its specifically causing a problem.

    If you could elaborate on the points I did not, or do not understand would be GREAT...

    Updated code is:

    Java Code:
    public class TabbedPanes extends JPanel {
        JTabbedPane tabbedPane = new JTabbedPane(); 
    	Timer swingTimer = new Timer(800, new TimerAction());
    
    	public TabbedPanes() {
            Dimension d = new Dimension(300,400);
        	JComponent panels;
    
            for(int i=0;i<1; i++){
            	panels = makeTextPanel("Panel #"+i);
            	panels.setPreferredSize(d);
            	tabbedPane.addTab("Tab "+i, null, panels, "Cool");
            	tabbedPane.setMnemonicAt(i, KeyEvent.VK_0);
            }
    
            tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
            mainPanel.add(tabbedPane); 
            swingTimer.start();
        }
        
        protected JComponent makeTextPanel(String text) {
            Dimension i = new Dimension(280,260);
            Dimension o = new Dimension(280,100);
            JPanel panel = new JPanel(false);
        	JTextArea incomingArea;
        	JTextArea outgoingArea;
        	JScrollPane scrollPane;
        	JScrollPane outgoingPane;
        	JButton test;
         
            incomingArea = new JTextArea(4,20);
            outgoingArea = new JTextArea(4,20);
    		incomingArea.setLineWrap(true);incomingArea.setWrapStyleWord(true); incomingArea.setName("Incoming"); 
            incomingArea.setEditable(false); incomingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setWrapStyleWord(true); outgoingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setLineWrap(true); outgoingArea.setName("Outgoing");
            outgoingPane = new JScrollPane(outgoingArea); incomingArea.setName("lawl");
    		scrollPane = new JScrollPane(incomingArea); scrollPane.setName("Incoming"); outgoingPane.setName("Outgoing");
    		scrollPane.setPreferredSize(i); outgoingPane.setPreferredSize(o);
            panel.setName("A new Panel");
            test = new JButton("Send");
            panel.add(scrollPane); 		// Component 0
            panel.add(outgoingPane); 	// Component 1
            panel.add(test); 			// Component 2
            incomingArea.setVisible(false);
            panel.add(incomingArea);
            return panel;
        }
        public void myPaint(Graphics g){
        	
        }
    	private class TimerAction implements ActionListener {
    		public void actionPerformed(ActionEvent arg0) {
    			JPanel j = (JPanel) tabbedPane.getComponentAt(0); //
    			JScrollPane inc = (JScrollPane) j.getComponent(0);
    			JTextArea i = (JTextArea) j.getComponent(3);
    			i.append("Lawl it worked..");
    			mainPanel.repaint();
    		}
    	}
    	public JPanel mainPanel = new JPanel() {
    		protected void paintComponent(Graphics g) {
    			super.paintComponent(g);
    			myPaint(g);
    		}
    	};
    	
    	public Component getJPanel(){
    		return mainPanel;
    	}
    
        private static void createAndShowGUI() {
            JFrame frame = new JFrame("BChat Messenger");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TabbedPanes().getJPanel(), BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
    		createAndShowGUI();
                }
            });
        }
    }

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    2.) I'm a little confused by this one. I understand what you are saying. As I re-evaluated my code though, I found that the TextAreas don't need to be added to any Component. They are merely needed by the ScrollPane to display the text. So I am setting the ScrollPane's ViewportView to the TextAreas. Now the question is, do I need to add these textAreas to the panel as well, and make them visible(false) so I keep them?
    You typically add a JTextArea to a JScrollPane's viewport and then add the JScrollPane to a container.


    3.) Why create a class for this instead of just using the method I've already got? I can't imagine doing anything different with a class. I'd create a class, and a constructor, pass the same variables into the constructor as the method, and be returning a JPanel still right?
    This is the crux of solving one of your main problems: associating components with a tabbed pane. You encapsulate all the components that are being held together in a class, and then associate objects of that class with the tabbed pane. You can then place these guys into a Map<JTabbedPane, TabPanel> and easily get a handle on what you need. Note my getter and setter methods don't return the components (except the getMainPanel method).

    4.) The current layout looks good on my screen and I'd like to stay with it unless you see its specifically causing a problem.
    In short, FlowLayout is a very dumb layout (in that it can only do few things and these not well) and is very inflexible. If your app is displayed on a machine with a different resolution, it may not work well. For instance when I ran your app on my laptop, I couldn't see the button on the bottom.

  6. #6
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    Java Code:
        	JPanel panels;
    
            for(int i=0;i<1; i++){
            	//panels = makeTextPanel("Panel #"+i);
            	panels = new TabPanelable();
            	panels.setPreferredSize(d);
            	tabbedPane.addTab("Tab "+i, null, panels, "Cool");
            	tabbedPane.setMnemonicAt(i, KeyEvent.VK_0);
            }
    The above is causing a problem.

    And besides the methods not being implemented, is this ideally what my class should look like?

    Java Code:
    class TabPanelable {
        Dimension i = new Dimension(280,260);
        Dimension o = new Dimension(280,100);
        JPanel panel = new JPanel(false);
        JTextArea incomingArea;
        JTextArea outgoingArea;
        JScrollPane scrollPane;
        JScrollPane outgoingPane;
        JButton test;
    
    	public TabPanelable(){
            incomingArea = new JTextArea(4,20);
            outgoingArea = new JTextArea(4,20);
    		incomingArea.setLineWrap(true);incomingArea.setWrapStyleWord(true); incomingArea.setName("Incoming"); 
            incomingArea.setEditable(false); incomingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setWrapStyleWord(true); outgoingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setLineWrap(true); outgoingArea.setName("Outgoing");
            outgoingPane = new JScrollPane(outgoingArea); incomingArea.setName("lawl");
    		scrollPane = new JScrollPane(incomingArea); scrollPane.setName("Incoming"); outgoingPane.setName("Outgoing");
    		scrollPane.setPreferredSize(i); outgoingPane.setPreferredSize(o);
            panel.setName("A new Panel");
            test = new JButton("Send");
            panel.add(scrollPane); 		// Component 0
            panel.add(outgoingPane); 	// Component 1
            panel.add(test); 			// Component 2
            incomingArea.setVisible(false);
            panel.add(incomingArea);
    	}
    }
    Not sure what is up with the tabbing in the code, it comes out of Eclipse looking fine. Anyways, as you said, the Class should just group my Components. So the constructor just does what my method was doing in the previous code. Sets up each component with the specific details, adds them to the panel etc.

    Now the question is how to take this class, and add it to my mainPanel in the TabbedPanes class.
    Last edited by Moncleared; 09-19-2009 at 05:30 AM.

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    OK, well let me know when you're back. I can show you some ideas, but again, also please let us know the ultimate goal of the project and what it's for (school project, commercial, hobby, etc..) Best of luck.

  9. #9
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    My apologies, I fell asleep last night working on this.

    This is just a hobby for me. I've created a server/client messaging system and the current window I have in place is too plain/jane. I wanted to add Tabs to it. So I've been working on this TabbedPanes on the side to see if I would actually be able to take this idea and merge it into my client messaging system.

    So far it looks like I should be able to. I just need to be able to access individual components in each tab (as you suggested, a HashMap should work). The tricky part will be when a client opens/closes tabs making sure everything is removed from the HashMap properly etc.

    Thanks for the help so far, does this give you an idea?

  10. #10
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    Java Code:
    	public JPanel getPanel(){
    		return panel;
    	}
    I stuck this in my TabPanelable class so that in my TabbedPanes class when I create a new Tab I can do this

    Java Code:
    for(int i=0;i<5; i++){
            	//panels = makeTextPanel("Panel #"+i);
            	panels = new TabPanelable().getPanel();
            	panels.setPreferredSize(d);
            	tabbedPane.addTab("Tab "+i, null, panels, "Cool");
            	tabbedPane.setMnemonicAt(i, KeyEvent.VK_0);
            }
    This came to me in my sleep last night =/

    My problem with this is now I have no way of keeping track of the Class itself. I feel like I should probably do something like create the class into a variable, use the variable.getClass() to pass the panel to tabbedPane. But then I have to keep track of each class in an array style, which is kind of what I was hoping to avoid.
    Last edited by Moncleared; 09-19-2009 at 04:20 PM.

  11. #11
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    Java Code:
        	LinkedList<TabPanelable> tabs = new LinkedList<TabPanelable>();
    
            	tabs.add(new TabPanelable());
            	panels = tabs.getLast().getPanel();
    This seems to be a good idea?

  12. #12
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    Java Code:
    public class TabbedPanes extends JPanel {
        JTabbedPane tabbedPane = new JTabbedPane(); 
    	LinkedList<TabPanelable> tabs = new LinkedList<TabPanelable>();
    	Timer swingTimer = new Timer(800, new TimerAction());
    
    	public TabbedPanes() {
            Dimension d = new Dimension(300,400);
        	JPanel panels;
    
            for(int i=0;i<1; i++){
            	//panels = makeTextPanel("Panel #"+i);
            	tabs.add(new TabPanelable());
            	panels = tabs.getLast().getPanel();
            	panels.setPreferredSize(d);
            	tabbedPane.addTab("Tab "+i, null, panels, "Cool");
            	tabbedPane.setMnemonicAt(i, KeyEvent.VK_0);
            }
    
            tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
            mainPanel.add(tabbedPane); 
            swingTimer.start();
        }
    
        public void myPaint(Graphics g){
        	
        }
    	private class TimerAction implements ActionListener {
    		public void actionPerformed(ActionEvent arg0) {
    			tabs.getFirst().incomingMsg("SUP YO");
    			tabs.getFirst().incomingArea.append("HAHA");
    			mainPanel.repaint();
    		}
    	}
    	public JPanel mainPanel = new JPanel() {
    		protected void paintComponent(Graphics g) {
    			super.paintComponent(g);
    			myPaint(g);
    		}
    	};
    	
    	public Component getJPanel(){
    		return mainPanel;
    	}
    
        private static void createAndShowGUI() {
            JFrame frame = new JFrame("BChat Messenger");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TabbedPanes().getJPanel(), BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
    		createAndShowGUI();
                }
            });
        }
    }
    
    class TabPanelable {
        Dimension i = new Dimension(280,260);
        Dimension o = new Dimension(280,100);
        JPanel panel = new JPanel(false);
    	JTextArea incomingArea;
    	JTextArea outgoingArea;
    	JScrollPane scrollPane;
    	JScrollPane outgoingPane;
    	JButton test;
    	public TabPanelable(){
            incomingArea = new JTextArea(4,20);
            outgoingArea = new JTextArea(4,20);
    		incomingArea.setLineWrap(true);incomingArea.setWrapStyleWord(true); incomingArea.setName("Incoming"); 
            incomingArea.setEditable(false); incomingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setWrapStyleWord(true); outgoingArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            outgoingArea.setLineWrap(true); outgoingArea.setName("Outgoing");
            outgoingPane = new JScrollPane(outgoingArea); incomingArea.setName("lawl");
            [B]scrollPane = new JScrollPane(incomingArea);[/B] scrollPane.setName("Incoming"); outgoingPane.setName("Outgoing");
    	scrollPane.setPreferredSize(i); outgoingPane.setPreferredSize(o);
            panel.setName("A new Panel");
            test = new JButton("Send");
            [B]panel.add(scrollPane);[/B] 		// Component 0
            panel.add(outgoingPane); 	// Component 1
            panel.add(test); 			// Component 2
    	}
    	public JPanel getPanel(){
    		return panel;
    	}
    	public void incomingMsg(String str){
    		incomingArea.append(str);
    		System.out.println("Called...");
    	}
    }
    We're back to square one.

    The LinkedList is working perfectly. I can access individual components as I need. But within the code posted above, the appending done in the timer NEVER updates to the screen.

    Notice that in the Tab class I have the incomingArea set to the viewportview of the ScrollPane and the scrollPane added to the panel.

    There has to be some simple concept I'm missing here.
    Last edited by Moncleared; 09-19-2009 at 04:44 PM.

  13. #13
    Moncleared is offline Member
    Join Date
    Jan 2009
    Posts
    92
    Rep Power
    0

    Default

    It works actually, I found the stupid mistake. Thanks Fubar

  14. #14
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    no prob. Since you've solved it, I'll show you my solution. Perhaps it can give you some ideas.

    TabPanel.java
    Java Code:
    import java.awt.event.ActionListener;
    import javax.swing.*;
    
    public class TabPanel  {
      private JPanel mainPanel = new JPanel();
      private JTextArea incomingArea = new JTextArea(18, 30);
      private JTextField outgoingField = new JTextField(30);
      private JButton sendButton = new JButton("Send");
      private int panelNumber;
      
      public TabPanel(int panelNumber) {
        this.panelNumber = panelNumber;
        
        JPanel btnPanel = new JPanel();
        btnPanel.add(sendButton);
        
        incomingArea.setEditable(false);
        incomingArea.setFocusable(false);
        incomingArea.setLineWrap(true);
        incomingArea.setWrapStyleWord(true);
    
        JScrollPane inScroll = new JScrollPane(incomingArea);
        JScrollPane outScroll = new JScrollPane(outgoingField,
            JScrollPane.VERTICAL_SCROLLBAR_NEVER,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
        mainPanel.add(inScroll);
        mainPanel.add(Box.createVerticalStrut(8));
        mainPanel.add(new JScrollPane(outScroll));
        mainPanel.add(btnPanel);
      }
    
      public void appendIncomingAreaText(String text) {
        incomingArea.append(text);
      }
      
      public String getOutGoingAreaText() {
        return outgoingField.getText();
      }
      
      public void setOutGoingAreaText(String text) {
        outgoingField.setText(text);
      }
      
      public void addSendActionListener(ActionListener al) {
        sendButton.addActionListener(al);
        outgoingField.addActionListener(al);
      }
      
      public JPanel getMainPanel() {
        return mainPanel;
      }
      
      public int getPanelNumber() {
        return panelNumber;
      }
    
      public void setPanelNumber(int i) {
        panelNumber = i;
      }
    }

    TabPanelPane.java
    Java Code:
    import java.awt.Window;
    import java.awt.Dialog.ModalityType;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.util.Random;
    
    import javax.swing.*;
    
    public class TabPanelPane {
      private static final int[] MNEMONICS = {KeyEvent.VK_G, KeyEvent.VK_1,
        KeyEvent.VK_2, KeyEvent.VK_3, KeyEvent.VK_4};
      private static final int TIMER_DELAY = 1000;
      private JTabbedPane mainTabbedPanel = new JTabbedPane();
      //private Map<Integer, TabPanel> tabMap = new HashMap<Integer, TabPanel>();
      TabPanel[] tabPanels = new TabPanel[MNEMONICS.length];
      private JTextArea receivingArea = new JTextArea(24, 30);
      private Timer swingTimer = new Timer(TIMER_DELAY, new TimerAction());
    
      public TabPanelPane() {
        for (int i = 0; i < MNEMONICS.length; i++) {
          final TabPanel tabPanel = new TabPanel(i);
          tabPanel.addSendActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              String outText = tabPanel.getOutGoingAreaText();
              // TODO: send outText to recipient.  i.e.,
              receivingArea.append("From Tab " + tabPanel.getPanelNumber() + ":> " + outText + "\n");
              
              // display it in the incoming area
              tabPanel.appendIncomingAreaText("Sent: > " + outText + "\n");
              
              // clear outgoing area
              tabPanel.setOutGoingAreaText("");
            }
          });
          tabPanels[i] = tabPanel;
    
          String tabString = (i == 0) ? "General" : "Tab " + i;
    
          mainTabbedPanel.addTab(tabString, null, tabPanel.getMainPanel(), "Cool");
          mainTabbedPanel.setMnemonicAt(i, MNEMONICS[i]);
        }
        swingTimer.start();
        
        receivingArea.setEditable(false);
        receivingArea.setFocusable(false);
        receivingArea.setLineWrap(true);
        receivingArea.setWrapStyleWord(true);
        Window win = SwingUtilities.getWindowAncestor(mainTabbedPanel);
        JDialog receivingDialog = new JDialog(win, "Receiving Window", ModalityType.MODELESS);
        receivingDialog.getContentPane().add(new JScrollPane(receivingArea));
        receivingDialog.pack();
        receivingDialog.setVisible(true);
      }
    
      public JComponent getComponent() {
        return mainTabbedPanel;
      }
    
      private class TimerAction implements ActionListener {
        private int panelCounter = 0;
        private Random random = new Random();
    
        public void actionPerformed(ActionEvent e) {
          TabPanel tabPanel = tabPanels[panelCounter];
          StringBuilder sb = new StringBuilder();
          for (int i = 0; i < random.nextInt(7) + 1; i++) {
            for (int j = 0; j < random.nextInt(8) + 1; j++) {
              char c = (char)('a' + random.nextInt(26));
              sb.append(c);
            }
            sb.append(" ");
          }
          tabPanel.appendIncomingAreaText("To area "
                  + panelCounter + ":> ");
          tabPanel.appendIncomingAreaText(sb.toString() + "\n");
    
          panelCounter++;
          panelCounter %= MNEMONICS.length;
        }
      }
    
      private static void createAndShowUI() {
        JFrame frame = new JFrame("Main Tabbed Pane");
        frame.getContentPane().add(new TabPanelPane().getComponent());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    
      public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowUI();
          }
        });
      }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •