JoshM
JoshM

Reputation: 95

Convert Graphics2D to ImageIcon

Following from a previously asked question Java Swing selecting a panel, I am trying to change the icons shown in the example to miniaturised Graphics2D objects.

My program will have several panels, each with a Graphics2D drawing in them, and on clicking a panel, an enlarged view will appear nearby (also as shown in the example from the other question's answer.

My issue now is generating a small icon from the Graphics2D drawing in each panel. Currently, I am having trouble creating the icon and using it.

public class BiomorphPanel extends JPanel{

PointCalc pc = new PointCalc();
private JLabel label = new JLabel();
private ImageIcon icon;

public JLabel getLabel() {
    return label;
}

public BiomorphPanel(){
    this.add(label);
}

private void doDrawing(Graphics g){

    Graphics2D g2d = (Graphics2D) g;
    //g2d.scale(0.1, 0.1);
    BufferedImage img = new BufferedImage(31, 31, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2dIcon = (Graphics2D) img.getGraphics();

    drawAll(g2d);
    drawAll(g2dIcon);

    g2dIcon.setColor(Color.BLACK);
    g2dIcon.fillRect(0, 0, 31, 31);
    g2dIcon.drawImage(img, null, 0, 0);
    icon = new ImageIcon(img);
    //icon = new ImageIcon(gra);
}

 @Override
 public void paintComponent(Graphics g) {       
     Graphics2D g2 = (Graphics2D) g;
     //scaling and translating to fit into mini panels in GUI
    // g2.scale(0.15, 0.15);
     //g2.translate(-100.0, 0.0);
     super.paintComponent(g2);
     doDrawing(g2);
    }    

 public ImageIcon getIcon(){
     return icon;
 }

 public void drawAll(Graphics2D g2d){
        //draw head
        Polygon hPoints = pc.getHeadPoints();
        g2d.drawPolygon(hPoints);

        //draw eyes
        Pair<Polygon, Polygon> ePoints = pc.getAllEyePoints();
        g2d.drawPolygon(ePoints.x);
        g2d.drawPolygon(ePoints.y);

        //draw eyebrows
        Pair<HashMap<Integer, Pair<Integer, Integer>>, HashMap<Integer, Pair<Integer, Integer>>> ebPoints = pc.getEyebrowPoints();
        g2d.drawLine(ebPoints.x.get(0).x, ebPoints.x.get(0).y, ebPoints.x.get(1).x, ebPoints.x.get(1).y);
        g2d.drawLine(ebPoints.y.get(0).x, ebPoints.y.get(0).y, ebPoints.y.get(1).x, ebPoints.y.get(1).y);

        //draw nose
        HashMap<Integer, Pair<Integer, Integer>> nPoints = pc.getNosePoints();
        g2d.drawLine(nPoints.get(0).x, nPoints.get(0).y, nPoints.get(1).x, nPoints.get(1).y);
        g2d.drawLine(nPoints.get(1).x, nPoints.get(1).y, nPoints.get(2).x, nPoints.get(2).y);

        //draw mouth
        Pair<HashMap<Integer, Pair<Integer, Integer>>, HashMap<Integer, Pair<Integer, Integer>>> mPoints = pc.getMouthPoints();
        g2d.drawLine(mPoints.x.get(0).x, mPoints.x.get(0).y, mPoints.x.get(1).x, mPoints.x.get(1).y);
        g2d.drawLine(mPoints.x.get(1).x, mPoints.x.get(1).y, mPoints.x.get(2).x, mPoints.x.get(2).y);

        g2d.drawLine(mPoints.y.get(0).x, mPoints.y.get(0).y, mPoints.y.get(1).x, mPoints.y.get(1).y);
        g2d.drawLine(mPoints.y.get(1).x, mPoints.y.get(1).y, mPoints.y.get(2).x, mPoints.y.get(2).y);

 }

}

Above is where I try to create the ImageIcon.

public class ListDisplayPanel extends Component{

//private static final Icon icon = UIManager.getIcon("html.pendingImage");

private ListPanel listPanel = new ListPanel();
private BiomorphPanel displayPanel1 = new BiomorphPanel();
private BiomorphPanel displayPanel2 = new BiomorphPanel();
private Icon icon = displayPanel1.getIcon();
private JPanel dpHold = new JPanel();

private class ListPanel extends JPanel {

    private static final int N = 5;
    private DefaultListModel dlm = new DefaultListModel();
    private JList list = new JList(dlm);

    public ListPanel() {
        super(new GridLayout());
        for (int i = 0; i < N * N; i++) {
            String name = "Cell-" + String.format("%02d", i);
            dlm.addElement(name);
        }
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        list.setVisibleRowCount(N);
        list.setCellRenderer(new ListRenderer());
        list.addListSelectionListener(new SelectionHandler());
        this.add(list);
    }

    private class ListRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(JList list,
                Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(
                    list, value, index, isSelected, cellHasFocus);
            label.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
            label.setIcon(icon);
            label.setHorizontalTextPosition(JLabel.CENTER);
            label.setVerticalTextPosition(JLabel.BOTTOM);
            return label;
        }
    }

    private class SelectionHandler implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                displayPanel1.getLabel().setText((String) dlm.getElementAt(e.getLastIndex()));
                displayPanel2.getLabel().setText((String) dlm.getElementAt(e.getLastIndex()));
            }
        }
    }
}

private void display() {
    JFrame f = new JFrame("Test");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JSplitPane jsp = new JSplitPane();
    jsp.setLeftComponent(new JScrollPane(listPanel));
    JSplitPane jsp2 = new JSplitPane();
    jsp2.setTopComponent(displayPanel1);
    jsp2.setBottomComponent(displayPanel2);
    jsp.setRightComponent(jsp2);
    f.add(jsp);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
}

public static void main(String[] args) {
    /*EventQueue.invokeLater(() ->*/ {
        new ListDisplayPanel().display();
    };
}
}

And here is where I try to use the icon created. When I run the class, no icons appear for each 'cell' in the menu. Are the icons not created correctly or are they not used correctly? I cannot tell.

Thank you

Upvotes: 1

Views: 2099

Answers (1)

trashgod
trashgod

Reputation: 205795

The key to this is creating a class that implements the Icon interface. Override the icon's paintIcon() method, which receives the suitable graphics context, and do your rendering there. Use the Component argument to retrieve properties and the x & y arguments to leverage the layout geometry. A complete example is seen here; more may be found here.

image

Upvotes: 4

Related Questions