Adding ViewPort to JPanel

I would like to do the following for my swing project, enter image description here

I was able to get this by extending JPanel and using JLayer. enter image description here

Event

I tried using AlphaComposite but it didn't work.

Edit1: I think JTable or JViewport can help me get what I want, but I don't know how to use them.

Edit2: Updated SSCCE, thanks trashgod for the suggestion. I used the Scalr library because after using the getScaledInstance method of the Image class, if I tried to use the getSubImage method of the BufferedImage, the following exception is thrown:

java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage

because the image generated by the getScaledInstance method is a ToolkitImage instance, so it cannot be distinguished from a BufferedImage.

If you don't want to use the Scalr library, you can use the code suggested in this to scale the BufferedImage and use the getSubImage method.

enter image description here

SCSE.java

import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.util.Random;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
import org.imgscalr.Scalr;

public class SCSE {

    private JFrame mainFrame;
    private JPanel mainPanel;
    private GridView gridView;
    private JButton imgBtn, shuffleBtn;
    private int gridX = -1, gridY = -1, gridWidth = -1, gridHeight = -1;
    private boolean isGridEmpty = false;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SCSE sc = new SCSE();

            sc.createGUI();

        });
    }

    private void createGUI() {

        mainFrame = new JFrame();
        mainFrame.setSize(500, 500);
        mainFrame.setResizable(false);
        mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        mainPanel = new JPanel(new BorderLayout());

        gridView = new GridView();

        imgBtn = new JButton("Get-Image");
        shuffleBtn = new JButton("Shuffle-ViewPort");
        imgBtn.addActionListener((ActionEvent evt) -> {
            try {
                gridView.setImage(ImageIO.read(new URL("http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg")));
            } catch (IOException ex) {
                System.out.println(ex);
            }
        });

        shuffleBtn.addActionListener((ActionEvent evt) -> {
            gridView.startShuffle();
        });

        mainPanel.add(gridView.getComponent(), BorderLayout.CENTER);
        mainPanel.add(imgBtn, BorderLayout.NORTH);
        mainPanel.add(shuffleBtn, BorderLayout.SOUTH);
        mainFrame.add(mainPanel);
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible(true);
    }

    class GridView {

        private Random shuffleRandom;
        private RegisterUI layerUi = null;
        private JLayer<JPanel> gridLayer = null;
        private ImagePanel mainPanel = null;
        private int gridNos = 21;   //number of grids
        int digit[];
        private int viewportDimensions = 4; //no of rows and columns in viewport
        private JLabel gridLabel[][] = new JLabel[gridNos][gridNos];
        private int gridX = -1, gridY = -1, gridWidth = -1, gridHeight = -1;
        private boolean isGridInitialized = false;

        public GridView() {
            initPersuasive();
            initPanel();
            initGrids();
        }

        private void initPanel() {
            mainPanel = new ImagePanel();
            mainPanel.setLayout(new GridLayout(gridNos, gridNos, 0, 0));                 //creates layout to place labels in grid form
            layerUi = new RegisterUI();
            gridLayer = new JLayer<>(mainPanel, layerUi);
        }

        private void initGrids() {
            for (int i = 0; i < gridNos; i++) {
                for (int j = 0; j < gridNos; j++) {
                    gridLabel[i][j] = new JLabel();
                    gridLabel[i][j].setOpaque(false);
                    gridLabel[i][j].setName("" + (i + 1));         // Since for loop index is 0 to 80, we add 1 to the name to make it 1 to 81
                    mainPanel.add(gridLabel[i][j]);              //add it to mainPanel
                }
            }
        }

        private void initPersuasive() {
            shuffleRandom = new Random();
            digit = new int[2];

        }

        private void random() {

            digit[0] = shuffleRandom.nextInt(gridNos - viewportDimensions);
            digit[1] = shuffleRandom.nextInt(gridNos - viewportDimensions);
        }

        public void startShuffle() {
            random();
            int x = gridLabel[digit[0]][digit[1]].getX();
            int y = gridLabel[digit[0]][digit[1]].getY();
            layerUi.placeViewport(x, y);
        }

        public void stopShuffle() {
            layerUi.removeViewPort();
        }

        public void setupGridView() {

            gridX = gridLabel[0][0].getX();
            gridY = gridLabel[0][0].getY();
            gridWidth = gridLabel[0][0].getWidth();
            gridHeight = gridLabel[0][0].getHeight();
            mainPanel.setValues(gridX, gridY);
            layerUi.setViewSize(gridWidth * viewportDimensions, gridHeight * viewportDimensions);

        }

        public void setImage(BufferedImage img) {
            if (!isGridInitialized) {
                setupGridView();
                isGridInitialized = true;
            }
            BufferedImage sendImg = Scalr.resize(img, Scalr.Mode.FIT_EXACT, gridWidth * gridNos, gridHeight * gridNos, Scalr.OP_ANTIALIAS);
            layerUi.setupViewport(img);
            mainPanel.paintImage(img);
        }

        public JLayer<JPanel> getComponent() {
            return gridLayer;
        }

    }

    class RegisterUI extends LayerUI<JPanel> {

        private int viewX, viewY, viewWidth, viewHeight;
        private boolean shuffleIsRunning = false;
        private BufferedImage viewportImage = null;

        private void drawPCCP(Graphics g, int w, int h) {
            Graphics2D g2 = ((Graphics2D) g);
            Color c = new Color(1.0f, 1.0f, 1.0f, 0.7f);
            g2.setPaint(c);
            g2.fillRect(0, 0, w, h);
            BufferedImage highlightGrid = Scalr.pad(Scalr.crop(viewportImage, viewX, viewY, viewWidth, viewHeight), 2, Color.BLACK, Scalr.OP_ANTIALIAS);
            g2.drawImage(highlightGrid, viewX, viewY, null);
            g2.dispose();
        }

        public void paint(Graphics g, JComponent c) {
            super.paint(g, c);
            int w = c.getWidth();
            int h = c.getHeight();
            if (shuffleIsRunning) {
                drawPCCP(g, w, h);
            }
        }

        public void setupViewport(BufferedImage bi) {
            viewportImage = bi;
        }

        public void setViewSize(int w, int h) {
            viewWidth = w;
            viewHeight = h;
        }

        public void placeViewport(int x, int y) {
            viewX = x;
            viewY = y;
            if (!shuffleIsRunning) {
                shuffleIsRunning = true;
            }
            firePropertyChange("shuffleui", 0, 1);

        }

        public void removeViewPort() {
            if (!shuffleIsRunning) {
                return;
            }
            viewX = 0;
            viewY = 0;
            viewWidth = 0;
            viewHeight = 0;
            shuffleIsRunning = false;
            firePropertyChange("shuffleui", 0, 1);
        }

        @Override
        public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends JPanel> l) {
            if ("disableui".equals(evt.getPropertyName()) || "shuffleui".equals(evt.getPropertyName())) {
                l.repaint();
            }
        }

    }

    class ImagePanel extends JPanel {

        private BufferedImage displayImage = null;
        private int x, y;

        public void setValues(int x, int y) {
            this.x = x;
            this.y = y;

        }

        public void paintImage(BufferedImage bi) {
            System.out.print(bi);
            displayImage = bi;
            repaint(); // repaint calls paintComponent method internally
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(displayImage, x, y, this);   // To Paint the image on the panel

        }
    }
}

      

+3


source to share


1 answer


Instead of using it AlphaComposite

directly as shown here , try RescaleOp

to change the color / alpha bands of an image as shown in the example. This will allow you to mute the entire image at will. Copy part of the original image with getSubimage()

to restore the selection.



+2


source







All Articles