在Java中调用repaint()时如何避免闪烁?

在Java中调用repaint()时如何避免闪烁?,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我已经看过许多类似问题的答案,但它们似乎都在说我在做一个JPanel,所以我不知道如何使我的矩形不闪烁 我正在制作一个屏幕截图,就像Mac电脑上的CMD+SHIFT+4功能一样。我让所有东西都工作了,也就是说,当你拖动一个矩形时,它会拍照,但是你选择的矩形会一直闪烁 import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.KeyE

我已经看过许多类似问题的答案,但它们似乎都在说我在做一个JPanel,所以我不知道如何使我的矩形不闪烁

我正在制作一个屏幕截图,就像Mac电脑上的CMD+SHIFT+4功能一样。我让所有东西都工作了,也就是说,当你拖动一个矩形时,它会拍照,但是你选择的矩形会一直闪烁

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.File;
import java.io.PrintWriter;
import javax.swing.*;
import javax.swing.event.*;
import javax.imageio.ImageIO;
import java.text.SimpleDateFormat;
import java.util.*;
import java.awt.geom.Area;

public class ScreenShotter extends JPanel implements MouseListener {

static JPanel contentPane;
private static JPanel picture1;
static int startX, startY, endX, endY;
static int width;
static int height;
int x,  y;
int radius = 2;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd kk.mm.ss");
static File f = new File("ScreenShotter.txt");
static String filePath = f.getPath();
static String screenshotPath = "";
JFileChooser chooser;
String chooserTitle = "Select the folder to store your screenshots";
static Point currentPoint;
static Point startPoint;
static boolean clicked = false;
static BufferStrategy bs;

public ScreenShotter() {
    setLayout(new BorderLayout());
    contentPane = new JPanel(new BorderLayout());
    contentPane.requestFocus();
    picture1 = new JPanel();    
    picture1.addMouseListener(this);
    picture1.setPreferredSize(new Dimension(width, height));
    contentPane.add(picture1);
}
public ScreenShotter(boolean bool){
    final String[] labels = {"Screen width: ", "Screen Height: "};
    int labelsLength = labels.length;
    final JTextField[] textField = new JTextField[labelsLength];

    final JPanel p = new JPanel(new SpringLayout());
    for(int i = 0; i < labelsLength; i++){
        JLabel l = new JLabel(labels[i], JLabel.TRAILING);
        p.add(l);
        textField[i] = new JTextField(10);
        l.setLabelFor(textField[i]);
        p.add(textField[i]);

    }
    final JButton button = new JButton("Submit");
    p.add(new JLabel());
    p.add(button);

    SpringUtilities.makeCompactGrid(p, 
                                    labelsLength + 1, 2,
                                    7, 7,
                                    7, 7);

    final JFrame frame = new JFrame("File Maker");
    button.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            //for(int i = 0; i < labels.length; i++){
            //System.out.println(labels[i]+"->"+textField[i].getText());
            //screenshotPath = textField[0].getText();
            width = Integer.parseInt(textField[0].getText());
            height = Integer.parseInt(textField[1].getText());
            //}
            chooser = new JFileChooser();
            chooser.setCurrentDirectory(new File("."));
            chooser.setDialogTitle(chooserTitle);
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            chooser.setAcceptAllFileFilterUsed(false);
            if(chooser.showOpenDialog(button) == JFileChooser.APPROVE_OPTION){
                System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory());
                System.out.println("getSelectedFile(): " + chooser.getSelectedFile());
                screenshotPath = slashConverter(chooser.getSelectedFile().toString());
            } else {
                System.out.println("No selection.");
            }
            frame.dispose();
            createFile();
        }
    });
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    p.setOpaque(true);
    frame.setContentPane(p);

    frame.pack();
    frame.setSize(210, 123);
    frame.setResizable(false);
    frame.setVisible(true);
}
@Override
public Dimension getPreferredSize(){
    return new Dimension(210, 123);
}
public static void main(String[] args){
    try {UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName());} 
    catch (UnsupportedLookAndFeelException e) {}
    catch (ClassNotFoundException e) {}
    catch (InstantiationException e) {}
    catch (IllegalAccessException e) {}
    if(f.exists()){
        width = getWidthFromFile(filePath);
        height = getHeightFromFile(filePath);
        startScreenShotter();
    }
    if(!f.exists()){
        JFrame fileMaker = new JFrame("File Maker");
        fileMaker.add(new ScreenShotter(true));
    }
}
public static void startScreenShotter(){
    JFrame frame = new JFrame("ScreenShotter");
    frame.add(new ScreenShotter());
    frame.setSize(width, height);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setUndecorated(true);
    frame.setOpacity(0.33f);
    frame.setContentPane(contentPane);
    frame.setVisible(true);
    frame.addKeyListener(new KeyListener(){
        public void keyPressed(KeyEvent ke) {
            if(ke.getKeyCode() == ke.VK_ESCAPE){
                System.exit(0);
            }
        }
        public void keyReleased(KeyEvent ke) {}
        public void keyTyped(KeyEvent ke) {}
    });
    while(true){
        currentPoint = MouseInfo.getPointerInfo().getLocation();
        if(currentPoint != startPoint && clicked){
            drawRectangle(startPoint, currentPoint, picture1);
        }
        //System.out.println(currentPoint);
        //delay(1);
    }
}
public static void drawRectangle(Point start, Point current, Object source){
    if(source instanceof JPanel){
        picture1.repaint();
        //delay(1);
        Rectangle r = new Rectangle(rectChecker(start.x, start.y, current.x, current.y));
        Graphics g = ((JComponent) source).getGraphics();
        g.fillRect((int)r.getX(), (int)r.getY(), (int)r.getWidth(), (int)r.getHeight());
        g.setColor(new Color(255, 255, 255, 50));
        //delay(1);
    }
}
public static void delay(int time){
    try{
        Thread.sleep(time);
    } catch(InterruptedException e){
        System.out.println("wot");
    }
}
public void mousePressed(MouseEvent e) {
    x = e.getX();
    y = e.getY();
    //drawCircle(e.getX()-(radius/2), e.getY()-(radius/2), e.getSource(), true);
    //repaint();
    startX = x;
    startY = y;
    startPoint = new Point(startX, startY);
    clicked = true;
    //System.out.println("(" + startX + ", " + startY + ")");
}
public void mouseReleased(MouseEvent e) {
    x = e.getX();
    y = e.getY();
    //drawCircle(e.getX()-(radius/2), e.getY()-(radius/2), e.getSource(), true);
    //repaint();
    endX = x;
    endY = y;
    //System.out.println("(" + endX + ", " + endY + ")");
    Frame[] f = Frame.getFrames();
    for(int i = 0; i < f.length; i++){
        f[i].dispose();
    }
    try {
        robo(rectChecker(startX, startY, endX, endY));
        System.exit(0);
    } catch(Exception ex){
        System.exit(1);
    }
}/*
public void drawCircle(int x, int y, Object source, boolean fill) {
    if(source instanceof JPanel) {
        Graphics g = ((JComponent) source).getGraphics();
        g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
        g.setColor(Color.RED);
        if (fill) {
            g.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
        }
    } // else ignore
}*/
public void robo(Rectangle r) throws Exception{
    Calendar now = Calendar.getInstance();
    Robot robot = new Robot();
    BufferedImage screenshot = robot.createScreenCapture(r);
    ImageIO.write(screenshot, "PNG", new File(getPath(filePath) + "Screenshot "+formatter.format(now.getTime())+".png"));
}
public static String getPath(String file){
    if(f.exists()){
        try(BufferedReader br = new BufferedReader(new FileReader(file))){
            String sCurrentLine;
            while((sCurrentLine = br.readLine()) != null){
                return sCurrentLine;
            }
        } catch(IOException e){
            e.printStackTrace();
        }
        return null;
    }
    return null;
}
public static int getWidthFromFile(String file){
    if(f.exists()){
        try(BufferedReader br = new BufferedReader(new FileReader(file))){
            br.readLine();
            int width = Integer.parseInt(br.readLine());
            return width;
        } catch(IOException e){
            e.printStackTrace();
        }
    }
    return 0;
}
public static int getHeightFromFile(String file){
    if(f.exists()){
        try(BufferedReader br = new BufferedReader(new FileReader(file))){
            br.readLine();
            br.readLine();
            int height = Integer.parseInt(br.readLine());
            return height;
        } catch(IOException e){
            e.printStackTrace();
        }
    }
    return 0;
}
public static Rectangle rectChecker(int x0, int y0, int x1, int y1){
    if(x0 > x1 && y0 < y1){
        int x = x1;
        int y = y0;
        int width = x0 - x1;
        int height = y1 - y0;

        Rectangle r = new Rectangle(x, y, width, height);
        return r;
    }
    if(x0 < x1 && y0 > y1){
        int x = x0;
        int y = y1;
        int width = x1 - x0;
        int height = y0 - y1;

        Rectangle r = new Rectangle(x, y, width, height);
        return r;
    }
    if(x0 > x1 && y0 > y1){
        int x = x1;
        int y = y1;
        int width = x0 - x1;
        int height = y0 - y1;

        Rectangle r = new Rectangle(x, y, width, height);
        return r;
    }
    int x = x0;
    int y = y0;
    int width = x1 - x0;
    int height = y1 - y0;

    Rectangle r = new Rectangle(x, y, width, height);
    return r;
}
public static void createFile(){
    System.out.println(width + " " + height + " " + filePath);
    try(PrintWriter writer = new PrintWriter(filePath, "UTF-8")){
        writer.println(screenshotPath);
        writer.println(width);
        writer.println(height);
        writer.close();
    } catch(IOException ioe){
        System.out.println("Call a doctor!");
    }
    startScreenShotter();
}
public static String slashConverter(String str){
    if(str.contains("\\")){
        str = str.replace("\\", "/");
        if(str.charAt(str.length()-1) != '/'){
            str = str + "/";
        }
        return str;
    }
    return str;
}
//public void mousePressed(MouseEvent e) {}
//public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
import java.awt.*;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.image.buffereImage;
导入java.awt.image.BufferStrategy;
导入java.io.FileReader;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.File;
导入java.io.PrintWriter;
导入javax.swing.*;
导入javax.swing.event.*;
导入javax.imageio.imageio;
导入java.text.simpleDataFormat;
导入java.util.*;
导入java.awt.geom.Area;
公共类ScreenShotter扩展JPanel实现MouseListener{
静态JPanel内容窗格;
私有静态JPanel图片1;
静态整数startX、startY、endX、endY;
静态整数宽度;
静态内高度;
int x,y;
int半径=2;
SimpleDataFormat格式化程序=新的SimpleDataFormat(“yyyy-MM-dd kk.MM.ss”);
静态文件f=新文件(“ScreenShotter.txt”);
静态字符串filePath=f.getPath();
静态字符串screenshotPath=“”;
JFileChooser选择器;
String chooserTitle=“选择用于存储屏幕截图的文件夹”;
静态点电流点;
静态点起始点;
静态布尔值=false;
静态缓冲策略;
公众截屏者(){
setLayout(新的BorderLayout());
contentPane=newjpanel(newborderlayout());
contentPane.requestFocus();
picture1=新JPanel();
图1.addMouseListener(本);
图1.设置首选尺寸(新尺寸(宽度、高度));
contentPane.add(图1);
}
公共屏幕截图(布尔布尔布尔){
最终字符串[]标签={“屏幕宽度:”,“屏幕高度:”};
int labelsLength=labels.length;
最终JTextField[]textField=新JTextField[标签长度];
final JPanel p=newjpanel(newspringlayout());
for(int i=0;i”+textField[i].getText());
//screenshotPath=textField[0]。getText();
width=Integer.parseInt(textField[0].getText());
height=Integer.parseInt(textField[1].getText());
//}
chooser=newjfilechooser();
chooser.setCurrentDirectory(新文件(“.”);
选择器.setDialogTitle(选择器标题);
setFileSelectionMode(仅限于JFileChooser.DIRECTORIES_);
选择器.setAcceptableFileFilterUsed(false);
if(chooser.showOpenDialog(按钮)=JFileChooser.APPROVE\u选项){
System.out.println(“getCurrentDirectory():”+chooser.getCurrentDirectory());
System.out.println(“getSelectedFile():”+chooser.getSelectedFile());
screenshotPath=slashConverter(chooser.getSelectedFile().toString());
}否则{
System.out.println(“无选择”);
}
frame.dispose();
createFile();
}
});
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
p、 set不透明(true);
frame.setContentPane(p);
frame.pack();
帧设置大小(210123);
frame.setresizeable(false);
frame.setVisible(true);
}
@凌驾
公共维度getPreferredSize(){
返回新维度(210123);
}
公共静态void main(字符串[]args){
请尝试{UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
捕获(无支持的LookandFeelexception e){}
catch(classnotfound异常){}
catch(实例化异常e){}
捕获(非法访问例外){}
如果(f.exists()){
宽度=getWidthFromFile(文件路径);
高度=getHeightFromFile(文件路径);
startScreenShotter();
}
如果(!f.exists()){
JFrame fileMaker=新的JFrame(“文件生成器”);
添加(新屏幕快照(true));
}
}
公共静态void startScreenShotter(){
JFrame=新的JFrame(“屏幕快照”);
frame.add(新的ScreenShotter());
框架尺寸(宽度、高度);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架。设置未装饰(真实);
帧不透明度(0.33f);
frame.setContentPane(contentPane);
frame.setVisible(true);
frame.addKeyListener(新的KeyListener(){
按下公共无效键(KeyEvent ke){
if(ke.getKeyCode()==ke.VK_ESCAPE){
系统出口(0);
}
}
public void keyreased(KeyEvent ke){}
public void keyTyped(KeyEvent ke){}
});
while(true){
currentPoint=MouseInfo.getPointerInfo().getLocation();
if(currentPoint!=开始点&&clicked){
绘图矩形(起点、当前点、图片1);
}
//系统输出打印项次(currentPoint);
//延迟(1);
}
}
公共静态void drawRectangle(点起点、点当前、对象源){
if(JPanel的源实例){
图1.重新绘制();
//延迟(1);
矩形
Graphics g = ((JComponent) source).getGraphics();
while (true) {
    currentPoint = MouseInfo.getPointerInfo().getLocation();
    if (currentPoint != startPoint && clicked) {
        drawRectangle(startPoint, currentPoint, picture1);
    }
//System.out.println(currentPoint);
    //delay(1);
}