私は、ユーザがウィンドウ内のJButtonをクリックし、ウィンドウ内のどこかをクリックすることで四角形または円を作成できるプログラムを作成しようとしていますボタン)をクリックします。PaintComponent()メソッドがmouseMoved()で呼び出されていない
私は現在、Shape型(squareとcircleの両方を実装するインターフェイス)のarrayListにSquareまたはCircleを追加する異なるボタンに2つのactionListenersを使用しています。 MouseListenerとMouseMotionListenerを実装するframeListenerというクラスがあります。MouseListenerとMouseMotionListenerは、マウスの移動時に四角形または円の位置を更新し、マウスがウィンドウを離れる場合は四角形または円形を削除し、マウスをクリックした場合は更新を停止します。永久に)。
また、JPanelを拡張するMyPanelというクラスがあり、paintComponent(Graphics g)メソッドを使用して背景に四角形と円をペイントします。 Shapeインタフェースのための
package smys01;
import java.util.ArrayList;
import java.text.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class SMYS01 extends JFrame {
private Color c = new Color(0, 0, 0);
private static ArrayList<Shape> shapes = new ArrayList();
private static ArrayList<Shape> deleted = new ArrayList();
private Point a;
private boolean makeSquare = false, makeCircle = false, makeSquiggle = false;
public static void main(String[] args) {
SMYS01 window = new SMYS01();
}
//good main
//0 is empty for making things, 1 is having a square selected to change, 2 is background;
private JButton makeSquareB = new JButton("New Square" /*, add icon later*/);
private JButton makeCircleB = new JButton("New Circle");
private Color background = new Color(0, 150, 0);
public SMYS01() {
makeSquareB.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("making square");
if(!makeCircle&&!makeSquare){
makeSquare = true;
shapes.ensureCapacity(shapes.size());
shapes.add(new Square((int) a.getX(), (int) a.getY(), c));
}else if(makeSquare){
}else if(makeCircle){
makeCircle=false;
makeSquare=true;
shapes.remove(shapes.size()-1);
shapes.ensureCapacity(shapes.size());
shapes.add(new Square((int) a.getX(), (int) a.getY(), c));
}
}
});
makeCircleB.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("making circle");
if(!makeCircle&&!makeSquare){
makeCircle = true;
shapes.ensureCapacity(shapes.size());
shapes.add(new Circle((int) a.getX(), (int) a.getY(), c));
}else if(makeCircle){
}else if(makeSquare){
makeSquare=false;
shapes.remove(shapes.size()-1);
shapes.ensureCapacity(shapes.size());
shapes.add(new Circle((int) a.getX(), (int) a.getY(), c));
}
}
});
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
MyPanel thing = new MyPanel();
frame.addMouseListener(new FrameListener());
frame.setContentPane(thing);
frame.setSize(thing.getPreferredSize());
frame.setTitle("Art!");
frame.addMouseMotionListener(new FrameListener());
}
private class MyPanel extends JPanel {
public MyPanel() {
GroupLayout layout = new GroupLayout(this);
layout.setHorizontalGroup(
layout.createSequentialGroup()
.addComponent(makeCircleB)
.addComponent(makeSquareB)
);
layout.setVerticalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(makeCircleB)
.addComponent(makeSquareB)
)
);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(background);
g.drawRect((int)g.getClipBounds().getX(),(int)g.getClipBounds().getY(),(int)g.getClipBounds().getWidth(),(int)g.getClipBounds().getHeight());
g.fillRect((int)g.getClipBounds().getX(),(int)g.getClipBounds().getY(),(int)g.getClipBounds().getWidth(),(int)g.getClipBounds().getHeight());
System.out.println(shapes.size());
for (Shape i : shapes) {
int[] a = i.getDim();
g.setColor(new Color(a[4], a[5], a[6], a[7]));
if(i instanceof Square){
g.drawRect(a[0], a[1], a[2], a[3]);
g.fillRect(a[0], a[1], a[2], a[3]);
}else if(i instanceof Circle){
g.drawOval(a[0], a[1], a[2], a[3]);
g.fillOval(a[0], a[1], a[2], a[3]);
}
}
}
}
class FrameListener implements MouseListener, MouseMotionListener {
public void mousePressed(MouseEvent e) {
System.out.println("pressed");
a = new Point(e.getPoint());
if (makeSquare) {
makeSquare = false;
System.out.println("square made!");
}
if (makeCircle) {
makeCircle = false;
System.out.println("cirlce made!");
}
//use this for sliders, nothing else.
}
public void mouseReleased(MouseEvent e) {
System.out.println("released");
a = new Point(e.getPoint());
//use for sliders, nothing else.
}
public void mouseClicked(MouseEvent e) {
System.out.println("clicked");
a = new Point(e.getPoint());
//don't need this
//makeSquare = false;
//makeCircle = false;
//makeSquiggle too.
}
public void mouseMoved(MouseEvent e) {
//showing up as false atm
a = new Point(e.getPoint());
System.out.println(a);
if (makeSquare||makeCircle) {
Shape b = shapes.get(shapes.size()-1);
b.updateLocation((int) a.getX(), (int) a.getY());
}
}
public void mouseDragged(MouseEvent e) {
//only check if over a JSlider
}
//complete methods:
public void mouseEntered(MouseEvent e) {
System.out.println("entered");
//nothing, Mouse re-entering doesn't effect the program.
}
public void mouseExited(MouseEvent e) {
System.out.println("exited");
makeSquare = false;
makeCircle = false;
makeSquiggle = false;
//if mouse leaves the window while trying to make one of these, stop it.
}
}
}
コード:スクエア
package smys01;
public interface Shape {
public void updateLocation(int newXPos, int newYPos);
public void updateDimensions(int newXDim, int newYDim);
public void delete();
public void purge();
public void restore();
public int[] getDim();
}
コード: 注意!このコードはちょっと書かれていて、関連性のない部分もありますが、完全に使用されていない部分もあります。これは、コンストラクタのためのものである、updateDimensions()メソッド、およびupdateLocation()メソッド
package smys01;
import java.awt.Color;
public class Square implements Shape{
//tbr=to be returned.
boolean deleted=false;
boolean purged=false;
private int xPos, yPos, xDim, yDim;
private int saveXPos, saveYPos, saveXDim, saveYDim, saveR, saveG, saveB, saveA;
private Color fill;
public Square(int initX, int initY, Color a){
xPos=initX;
yPos=initY;
xDim=50;
yDim=50;
fill=a;
}
public void updateDimensions(int newXDim, int newYDim){
if(purged||deleted)
return;
if(newXDim<=2){
xDim=2;
}else{
xDim=newXDim;
}
if(newYDim<=2){
yDim=2;
}else{
yDim=newYDim;
}
}
public void updateLocation(int newXPos, int newYPos){
if(purged){
return;
}
if(newXPos<=5){
xPos=5;
}else{
xPos=newXPos;
}
if(newYPos<=25){
yPos=25;
}else{
yPos=newYPos;
}
}
public void delete(){
if(!deleted){
saveXPos=xPos;
saveYPos=yPos;
saveXDim=xDim;
saveYDim=yDim;
saveR=fill.getRed();
saveB=fill.getBlue();
saveG=fill.getGreen();
saveA=fill.getAlpha();
deleted=true;
xPos=-5;
yPos=-5;
xDim=1;
yDim=1;
}
}
public void purge(){
saveXPos=-10;
saveYPos=-10;
saveXDim=3;
saveYDim=3;
//use in an if statement, and if true (will be, set the square value to null, so this reference will go away, preventing data overflow
}
public void restore(){
xPos=saveXPos;
yPos=saveYPos;
xDim=saveXDim;
yDim=saveYDim;
deleted=false;
}
public int[] getDim(){
int[] tbr={xPos,yPos, xDim, yDim,fill.getRed(), fill.getBlue(), fill.getGreen(), fill.getAlpha()};
return tbr;
}
public String toString(){
String tbr="Square: ("+xPos+", "+yPos+"); ("+xDim+", "+yDim+"); ("+fill.toString();
return tbr;
}
}
Circleクラスのためのコードはまったく同じであるが、オブジェクトの種類は、それらを区別するためにpaintComponentメソッドを可能にします。
mouseMovedが呼び出されたときにpaintComponentを呼び出そうとしていますが、これを行うようには思えません。私はrepaint()を使って試してみましたが、これを理解しようと数時間見ました。
これまでのところ、基本的にSwingは必要なときに(ウィンドウサイズが変更されたとき、またはウィンドウが最小化されて再オープンされたとき)paintComponentを呼び出します。
しかし、私はボタンを押したりマウスを動かすとどのように呼び出すのか不明です。これに対してrepaint()は機能しません。
コードの一部が不適切な場合は謝罪し、数回書き直し、いくつかの部分は不要ですがまだそこにあります。
匿名のアクションクラスまたはFrameListenerクラスからpaintComponentメソッドを積極的に呼び出す方法はありますか?
'repaint'を呼び出してみましたか?あなたの問題を示す[実行可能な例](https://stackoverflow.com/help/mcve)を提供することを検討してください。これはコードダンプではありませんが、あなたがしていることの例はあなたが持っている問題を強調表示します。これにより、混乱が少なくなり、応答が改善されます。 – MadProgrammer
@MadProgrammerはい、mousePressed()とmouseMoved()の両方でrepaintを呼び出そうとしましたが、何もしません。実行可能な例の代わりに上記の完全なコードを取り上げます。 –
次に、有効な[mcve]を作成したいと思うでしょうし、実際には最小限の**コンパイルと実行が可能で、外部の依存関係(データベースやイメージなど)もなく、お客様の問題を直接的に示しています。 –