Mohamed
Mohamed

Reputation: 83

Change the background slowly while scrolling

I'm trying to create a small program, that I want to change the background slowly while scrolling the scrollbar (JScrollPane). It's like onscroll function in Javascript.

I created the scroll pane and added to it a frame then put some components in it, what I want now, is when the user scrolls, the BG of the scroll pane changes slowly from black to white, when it reaches the bounds of the frame:

This how I created the frame and scroll pane:

public AdminFrame() {
    setBounds(20, 20, 1300, 700);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    getContentPane().setLayout(new BorderLayout(0, 0));
    
    JPanel contentPane = new JPanel();
    contentPane.setForeground(Color.WHITE);
    contentPane.setFont(new Font("Tahoma", Font.BOLD, 11));
    contentPane.setBounds(120, 50, 692, 7);
    contentPane.setPreferredSize(new Dimension(1300, 1500));
    getContentPane().add(contentPane, BorderLayout.CENTER);
    contentPane.setLayout(null);
    JScrollPane scrollPane=new JScrollPane(contentPane,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.setBackground(BgColor);
    scrollPane.getVerticalScrollBar().setUnitIncrement(25);
}

I tested many ideas, also many block of solutions that I found in the web but nothing works.

Like:

scrollPane.getViewport().addChangeListener(new ChangeListener() {
            
    @Override
    public void stateChanged(ChangeEvent e) {
        // TODO Auto-generated method stub
        contentPane.setBackground(Color.white);
        System.out.println("scorled");
        
    }
} )

Or:

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
            
    @Override
    public void adjustmentValueChanged(AdjustmentEvent e) {
        // TODO Auto-generated method stub
          scrollPane.setBackground(new Color(BgColor.getRed()-10,BgColor.getBlue()-10,BgColor.getGreen()-10)); //change the background color;
    }
});

Upvotes: 2

Views: 180

Answers (2)

Gilbert Le Blanc
Gilbert Le Blanc

Reputation: 51565

Introduction

Your "simple" project is not simple in Java. Java is not the same language as JavaScript. Simple things in JavaScript can be incredibly hard to duplicate in Java.

Here's a GUI I put together. This is the initial state.

Color Change 1

This is the state with the vertical scroll bar about halfway down.

Color Change 2

This is the state with the vertical scroll bar all the way down.

Color Change 3

Explanation

Oracle has a nifty tutorial, Creating a GUI With JFC/Swing that will take you through the many many steps to create a Swing GUI. Skip the Netbeans section.

I created a background JPanel. I placed the background JPanel inside a JScrollPane. I placed the JScrollPane inside the main JPanel. I placed the main JPanel inside a JFrame.

I started the Swing application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components will be created and executed on the Event Dispatch Thread.

I used Swing layout managers to layout the Swing components.

Code

Here's the complete runnable code. I made all the classes inner classes so I could post the code as one block.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class BackgroundColorChangeGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new BackgroundColorChangeGUI());
    }
    
    private final BackgroundColorChangeModel model;
    
    private BackgroundPanel backgroundPanel;
    
    public BackgroundColorChangeGUI() {
        this.model = new BackgroundColorChangeModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Color Change");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        backgroundPanel = new BackgroundPanel();
        Dimension d = backgroundPanel.getPreferredSize();
        int displayHeight = 400;
        panel.setPreferredSize(new Dimension(d.width + 50, displayHeight));
        
        JScrollPane scrollPane = new JScrollPane(backgroundPanel);
        
        JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
        scrollBar.setMaximum(d.height - displayHeight + 13);
        scrollBar.setUnitIncrement(1);
        model.setMinimumValue(scrollBar.getMinimum());
        model.setMaximumValue(scrollBar.getMaximum());
        scrollBar.addAdjustmentListener(new ScrollListener());
        
        panel.add(scrollPane);
        
        return panel;
    }
    
    public class BackgroundPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        public BackgroundPanel() {
            this.setPreferredSize(new Dimension(300, 5000));
            setBackgroundColor(Color.BLACK);
        }

        public void setBackgroundColor(Color backgroundColor) {
            this.setBackground(backgroundColor);
        }
        
    }
    
    public class ScrollListener implements AdjustmentListener {

        @Override
        public void adjustmentValueChanged(AdjustmentEvent event) {
//          System.out.println(event.getValue());
            Color color = createBackgroundColor(event.getValue());
            backgroundPanel.setBackgroundColor(color);
        }
        
        private Color createBackgroundColor(int value) {
            // Black is 0, 0, 0; white is 255, 255, 255
            int range = model.getMaximumValue() - model.getMinimumValue();
            int colorValue = value * 255 / range;
            return new Color(colorValue, colorValue, colorValue);
        }
        
    }
    
    public class BackgroundColorChangeModel {
        
        private int minimumValue;
        private int maximumValue;
        
        public int getMinimumValue() {
            return minimumValue;
        }
        
        public void setMinimumValue(int minimumValue) {
            this.minimumValue = minimumValue;
        }
        
        public int getMaximumValue() {
            return maximumValue;
        }
        
        public void setMaximumValue(int maximumValue) {
            this.maximumValue = maximumValue;
        }
        
    }

}

Upvotes: 3

Butiri Dan
Butiri Dan

Reputation: 1772

You should update the color for each event

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
    @Override
    public void adjustmentValueChanged(AdjustmentEvent evt) {
        int x = evt.getValue() % 255;
        contentPane.setBackground(new Color(x, x, x));
        System.out.println("scorled");
    }
});

Upvotes: 2

Related Questions