Domanda

Scroll bar disappears when clicked and when re-sizing -> old screen stays as well as part of the new screen appears in spots. Scroll bar disappears when clicked and when re-sizing window the center panel gets distorted (keeps old stale scroll bars and messes up text)

I'm creating a little old school text based adventure game for one of my classes. I'm new to using swing and am having problems with my central frame panel. The only part of my code I am having problems with is the scroll bar (see updateScreen() and GraphicView() constructor). Sorry if the code is hard to follow because this is just one of the many classes and there are comments of stuff i have previously tried that have the same problems.

See the simplified code at the bottom if you want to run it

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GraphicView extends View {

    public static void main(String[] args)
    {
        GraphicView view = new GraphicView();
    }
    GraphicView()
    {
        frame = new JFrame();
        frame.addWindowListener(new GuiWindowListener());
        frame.setLocation(100, 200);
        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        frame.setTitle("Nittany Cubs Gaming GUI");
        frame.setLayout(new BorderLayout());


        //JScrollPain mainPanel = new Panel();
    //  mainPanel = new JPanel();
    //  mainPanel.setLayout(new BorderLayout());

        //northButton = new JButton("Go North");
        //northButton.addActionListener(new NorthButtonActionListener());
        //eastButton = new JButton("Go east");
        //eastButton.addActionListener(new EastButtonActionListener());
        //southButton = new JButton("Go south");
        //southButton.addActionListener(new SouthButtonActionListener());
        //westButton = new JButton("Go west");
        //westButton.addActionListener(new WestButtonActionListener());
        //frame.add(westButton,BorderLayout.WEST);
        //frame.add(southButton,BorderLayout.SOUTH);
        //frame.add(eastButton,BorderLayout.EAST);
        //frame.add(northButton,BorderLayout.NORTH);


//      Panel southPanel = new Panel();
//      mainPanel.add(southPanel, BorderLayout.SOUTH);

    //  Panel northPanel = new Panel();
    //  northPanel.setSize(frame.getWidth(), 50);
    //  northPanel.setBackground(Color.BLACK);
        // add north button to north panel
    //  Button northButton = new Button("North Button");
    //  northButton.setSize(northPanel.getWidth()-10, northPanel.getHeight()-10);
        //northButton.setSize(northPanel.getSize());
        //northButton.setBounds(new Rectangle(northPanel.getBounds()));
        //northButton.setMaximumSize(northPanel.getSize());
    //  northButton.setBackground(Color.PINK);
    //  northButton.addActionListener(new NorthButtonActionListener());
    //  northPanel.add(northButton);
        // add north panel to main panel
    //  mainPanel.add(northPanel, BorderLayout.NORTH);

        northButton = new JButton("Go North");
        northButton.addActionListener(new NorthButtonActionListener());
        frame.add(northButton, BorderLayout.NORTH);

        eastButton = new JButton("Go east");
        eastButton.addActionListener(new EastButtonActionListener());
        frame.add(eastButton, BorderLayout.EAST);

        southButton = new JButton("Go south");
        southButton.addActionListener(new SouthButtonActionListener());
        frame.add(southButton, BorderLayout.SOUTH);

        westButton = new JButton("Go west");
        westButton.addActionListener(new WestButtonActionListener());
        frame.add(westButton, BorderLayout.WEST);

        text = "";
        mainPanel = new JPanel();
        textArea = new JTextArea(text);
        textArea.setEditable(false);
        //mainPanel.add(textArea);
        //scroller = new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scroller = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        frame.add(scroller,BorderLayout.CENTER);

        updateScreen();
    }

    private static void updateScreen()
    {
    //  JTextArea ta = new JTextArea(text);
        textArea = new JTextArea(text);
        //mainPanel.add(textArea);
        scroller = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        //scroller = new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        frame.add(scroller,BorderLayout.CENTER);
        frame.setVisible(true);

    //  JScrollPane scroller = new JScrollPane(ta);
      // disables editing
     //   ta.setEditable(false);
    //  scroller = new JScrollPane(ta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    //  scroller.setBounds(3, 3, 300, 200);

    //  label = new JLabel("<html>" + text + "</html>");

    //  label.setLayout(new BorderLayout());

    //  label.setVerticalAlignment(SwingConstants.TOP);
    //  scroller = new JScrollPane(label, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        //scroller.addMouseWheelListener(new MyMouseWheelListener());
//      scroller.createVerticalScrollBar();
//      scroller.createHorizontalScrollBar();
//      scroller.setAutoscrolls(true);


//      mainPanel.add(scroller, BorderLayout.CENTER);
//      frame.getContentPane().add(mainPanel);
//      frame.add(scroller,BorderLayout.CENTER);
//      frame.setVisible(true);
    }

    @Override
    public void informInvalidGoDirection(String direction) {
        text += "\nYou hit your nose on the wall trying to go " + direction + ". ";
        updateScreen();
    }

    @Override
    public void informPlayerMoved() {
        // TODO Auto-generated method stub

    }

    @Override
    public void look() {
        // TODO Auto-generated method stub
        Location currentLocation = Application.instance().playerCurrentLocation();
        text += currentLocation.description()  + " " + getItemsDescription(currentLocation) + " " +
                             getMobsDescription(currentLocation) + " " +
                             getCanMoveDirectionsDescription(currentLocation);
        updateScreen();
    }

    private class NorthButtonActionListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ev)
        {
            Location currentLocation = Application.instance().playerCurrentLocation();
            boolean isLocationValid = Application.instance().isThereALocationNorthOf(currentLocation);
            if(isLocationValid)
            {

                Application.instance().movePlayerNorth();

                Location newLocation = Application.instance().playerCurrentLocation();
                text = newLocation.description() +
                         getItemsDescription(newLocation) +
                         getMobsDescription(newLocation) +
                         getCanMoveDirectionsDescription(newLocation);
                updateScreen();
            }
            else
            {
                informInvalidGoDirection("north");
            }
        }
    }

    private class SouthButtonActionListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ev)
        {
            Location currentLocation = Application.instance().playerCurrentLocation();
            boolean isLocationValid = Application.instance().isThereALocationSouthOf(currentLocation);
            if(isLocationValid)
            {
                Application.instance().movePlayerSouth();

                Location newLocation = Application.instance().playerCurrentLocation();
                text = newLocation.description() +
                         getItemsDescription(newLocation) +
                         getMobsDescription(newLocation) +
                         getCanMoveDirectionsDescription(newLocation);
                updateScreen();
            }
            else
            {
                informInvalidGoDirection("south");
            }
        }
    }

    private class EastButtonActionListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ev)
        {
            Location currentLocation = Application.instance().playerCurrentLocation();
            boolean isLocationValid = Application.instance().isThereALocationEastOf(currentLocation);
            if(isLocationValid)
            {
                Application.instance().movePlayerEast();

                Location newLocation = Application.instance().playerCurrentLocation();
                text = newLocation.description() +
                         getItemsDescription(newLocation) +
                         getMobsDescription(newLocation) +
                         getCanMoveDirectionsDescription(newLocation);
                updateScreen();
            }
            else
            {
                informInvalidGoDirection("east");
            }
        }
    }

    private class WestButtonActionListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ev)
        {
            Location currentLocation = Application.instance().playerCurrentLocation();
            boolean isLocationValid = Application.instance().isThereALocationWestOf(currentLocation);
            if(isLocationValid)
            {
                Application.instance().movePlayerWest();                

                Location newLocation = Application.instance().playerCurrentLocation();
                text = newLocation.description() +
                         getItemsDescription(newLocation) +
                         getMobsDescription(newLocation) +
                         getCanMoveDirectionsDescription(newLocation);
                updateScreen();
            }
            else
            {
                informInvalidGoDirection("west");
            }
        }
    }


    private static class GuiWindowListener extends WindowAdapter
    {
        @Override
        public void windowClosing(WindowEvent ev)
        {
            ev.getComponent().setVisible(false);
            System.exit(0);
        } /* end windowClosing */
    } /* end GuiWindowListener */



    private static final int FRAME_HEIGHT = 480;
    private static final int FRAME_WIDTH = 640;
    private static JButton northButton;
    private static JButton southButton;
    private static JButton eastButton;
    private static JButton westButton;
//  private static JLabel label;
    private static String text;
    private static JPanel mainPanel;
    private static JScrollPane scroller;
    private static JFrame frame;
    private static JTextArea textArea;

}

Here is the simplified version to emphasize the problem i am having NOTE -> the scroll issue occurs until next time screenUpdate() occurs

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class GraphicViewSimplified {
    public static void main(String[] args)
    {
        GraphicViewSimplified view = new GraphicViewSimplified();
    }
    GraphicViewSimplified()
    {
        frame = new JFrame();
        frame.addWindowListener(new GuiWindowListener());
        frame.setLocation(100, 200);
        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        frame.setTitle("Nittany Cubs Gaming GUI");
        frame.setLayout(new BorderLayout());

        northButton = new JButton("Go North");
    //  northButton.addActionListener(new NorthButtonActionListener());
        frame.add(northButton, BorderLayout.NORTH);

        eastButton = new JButton("Go east");
    //  eastButton.addActionListener(new EastButtonActionListener());
        frame.add(eastButton, BorderLayout.EAST);

        southButton = new JButton("Go south");
    //  southButton.addActionListener(new SouthButtonActionListener());
        frame.add(southButton, BorderLayout.SOUTH);

        westButton = new JButton("Go west");
    //  westButton.addActionListener(new WestButtonActionListener());
        frame.add(westButton, BorderLayout.WEST);

        text = ";lakjd;lfkjasd;lfkjas;ldfkjas;lkdfj;a\naj;lsdkfjas;lkdjf\naal;skjfw;lk\n";
        //mainPanel = new JPanel();
        textArea = new JTextArea(text);
        textArea.setEditable(false);
        scroller = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        frame.add(scroller,BorderLayout.CENTER);

        while(true)
        {
            updateScreen();
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private static void updateScreen()
    {
        String alph = "abcdefghijklmnopqrstuvwxyz";

        int firstInt = (int)(Math.random()*100);
        int secondInt = (int)(Math.random()*100);

        for(int i = 0; i < firstInt ; i++)
        {

            text += alph.charAt((int)(Math.random()*alph.length()));
        }

        text += "\n";


        for(int i = 0; i < secondInt ; i++)
        {       
            text += alph.charAt((int)(Math.random()*alph.length()));
        }

        text += "\n";

    //  JTextArea ta = new JTextArea(text);
        textArea = new JTextArea(text);
        textArea.setEditable(false);
        //mainPanel.add(textArea);
        scroller = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        //scroller = new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        frame.add(scroller,BorderLayout.CENTER);
        frame.setVisible(true);

    }

    private static class GuiWindowListener extends WindowAdapter
    {
        @Override
        public void windowClosing(WindowEvent ev)
        {
            ev.getComponent().setVisible(false);
            System.exit(0);
        } /* end windowClosing */
    } /* end GuiWindowListener */

    private static final int FRAME_HEIGHT = 480;
    private static final int FRAME_WIDTH = 640;
    private static JButton northButton;
    private static JButton southButton;
    private static JButton eastButton;
    private static JButton westButton;
    private static String text;
//  private static JPanel mainPanel;
    private static JScrollPane scroller;
    private static JFrame frame;
    private static JTextArea textArea;
}
È stato utile?

Soluzione 2

Okay I figured out the answer to my own question I needed to add remove(OldComponents) revalidate() then add(newComponent) then revalidate() in the updateScreen() function. I got it working! Thanks for the help though

Altri suggerimenti

At first you block EDT here, it isn't right:

while (true) {
    updateScreen();
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

For that purpose you can use Swing Timer, it can be used for updating by interval, also 1500 maybe a big interval, because of you get lags when resizing frame.

Timer t = new Timer(1000, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
         updateScreen();
    }
});
t.start();

As for me seems you really need SwingWorker. Here is good example of that.

Read about concurrency in Swing, Swing Timer and SwingWorker.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top