简体   繁体   中英

Having trouble aligning graphics in Java

So I am using a JFrame object to open up a window and add a bunch of graphics first I am adding an image then I am trying to add some lines, But it seems like the line start from the Y center of the previous image I would like for it to start at the top of the page here is my code for the JFrame:

    JFrame f = new JFrame();
    JLabel trebeclef = new JLabel(new ImageIcon(getClass().getClassLoader().getResource("Some image")));
    Draw d = new Draw();
    f.add(trebeclef);
    f.add(d);   
    f.setSize(1000,1000);
    f.getContentPane().setBackground(Color.white);
    f.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
    f.pack();
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

here is the code for the Draw class

public void paint(Graphics g2) {
        super.paintComponent(g2);
        Graphics2D g = (Graphics2D) g2;
        g.setStroke(new BasicStroke(2));
        g.drawLine(0, 0, 100, 0);
    }

it results in this

在此处输入图像描述

Any help appreciated, thanks

Trying to layout components like this isn't the easiest thing to to, especially when you consider the complexities of JLabel and the possibilities of other layout constraints.

If you have the image and you're drawing the lines via custom painting, I would just custom paint the whole thing

Starting with...

在此处输入图像描述

We can produce something like...

在此处输入图像描述

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public final class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new ClefWithLinesPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class ClefWithLinesPane extends JPanel {

        private BufferedImage trebbleClef;

        public ClefWithLinesPane() throws IOException {
            trebbleClef = ImageIO.read(getClass().getResource("/images/ClefLines.png"));
            setBackground(Color.WHITE);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(800, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = 0;
            int y = (getHeight() - trebbleClef.getHeight()) / 2;
            g2d.drawImage(trebbleClef, x, y, this);

            int[] lines = new int[] {
                30, 60, 89, 120, 149
            };

            x = trebbleClef.getWidth();

            g2d.setStroke(new BasicStroke(2));
            for (int line = 0; line < lines.length; line++) {
                y = lines[line];
                g2d.drawLine(x, y, getWidth(), y);
            }

            g2d.dispose();
        }

    }
}

But... as you can see, the lines don't "quite" match up, now this is simply an issue with source image and you could spend some time cleaning it up, or, you could just dispense with the lines of the clef itself and do those you're self, for example...

Starting with...

在此处输入图像描述

We could produce something like...

在此处输入图像描述

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public final class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new ClefWithOutLinesPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class ClefWithOutLinesPane extends JPanel {

        private BufferedImage trebbleClef;

        public ClefWithOutLinesPane() throws IOException {
            trebbleClef = ImageIO.read(getClass().getResource("/images/Clef.png"));
            setBackground(Color.WHITE);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(800, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int minLineY = 30;
            int maxLineY = 150;

            int lineSpacing = (maxLineY - minLineY) / 4;

            int x = 10;

            g2d.setStroke(new BasicStroke(8));
            g2d.drawLine(x, minLineY + 3, x, maxLineY - 3);
            int y = (getHeight() - trebbleClef.getHeight()) / 2;
            g2d.drawImage(trebbleClef, x + 10, y, this);

            g2d.setStroke(new BasicStroke(2));
            for (int line = 0; line < 5; line++) {
                y = minLineY + (lineSpacing * line);
                g2d.drawLine(x, y, getWidth(), y);
            }

            g2d.dispose();
        }

    }
}

Adds after setLayout . One often uses an overloaded add with an extra parameter for a layout's specific constraint.

By default the content pane the frame's add s are done upon, has a BorderLayout with center, left and so on.

The horizontal "line" in a flow is vertically centered. Setting a preferred height ensures a line component is filled up.

d.setPreferredSize(new Dimension(100, 1000)); 

Of course an other layout might serve better; depending on what you want - just experiment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM