[질문] Swing에서 이벤트를 만들어 내려면 어떻게 해야 하나요??

tyolee83의 이미지

질문의 뜻이 제대로 전달되도록 최선을 다해 보겠습니다.

마우스를 클릭하거나 버튼을 클릭하면 이벤트가 발생하게 되잖아요...

이벤트 리스너가 그 이벤트를 받아서 처리하고...

그런데 이벤트 멀티캐스트를 위해 중간에 개념적인 Event Multicaster를 두려고 하거든요...

버튼이나 마우스에서 일어난 이벤트를 이 멀티캐스터가 보고

각각의 상황에서 이제 다른 컴포넌트들에게

정보를 가진 새로운 이벤트를 multicast 해야되는데(제가 직접 정의하는 이벤트이죠)

이 이벤트를 어떻게 만들어 내야 할지 모르겠습니다....

좀 더 구체적으로 말씀드리자면

캔버스에다가 원을 여러개 그리고

한 원을 선택할때, 마우스 이벤트가 멀티캐스터에게 전달되고

이 멀티캐스터가 각각의 원들에게 이벤트를 Multicast 하여

해당되는 원이 어떤것인지 파악하려는 것입니다.

while을 돌면서 하나하나 찾는게 아니라 multicast의 개념을 적용하려 하는 것입니다.

어떤 방법이 있는지 도움좀 부탁드립니다.

열심히 찾아봤는데 잘 모르겠어서 이렇게 질문 올립니다.

미리 감사드립니다.

mykldp의 이미지

음 바라시는 바를 정확히 짐작하기 힘들지만... 다음 같은 것을 말씀하시는 것인지. 코드는 정확치 않습니다만 내용은 전달되리라고 생각합니다 ^^;

interface CustomListener {
	public void execute(CustomEvent e);
}
 
class Multicaster {
	public Multicaster(Canvas c) {
		c.addMouseListener(new MouseListener() {
			public void ~~~(MouseEvent e) {
				for(CustomListener l : listeners) {
					CustomEvent e = new CustomEvent();
					l.execute(e);
				}
			}
		});
	}
 
	public void addListner(CustomListener l) {
		listeners.add(l);
	}
 
	private List listeners = new ArrayList();
}

그리고 각 원이 Multicaster 에 CustomListener 를 등록합니다.
class Circle  {
	public Circle(Multicaster m) {
		m.addListener(new CustomListener() {
			public void execute(CustomEvent e) {
				~~
			}
		});
	}
}
익명 사용자의 이미지

자동으로 마우스 클릭하고 키보드 입력하는것을 원하시는 거라면 스윙의 Robot 이라는 클래스를 확인해 보세요.

익명 사용자의 이미지

자동으로 마우스 클릭하고 키보드 입력하는것을 원하시는 거라면 스윙의 Robot 이라는 클래스를 확인해 보세요.

tyolee83의 이미지

일단 robot을 써보라고 하신 분께는, 질문이 그 의도가 아니라고 말씀드려야 할것 같구요~ ^^;

하지만, bot이라는 놈이 있다는 것을 알려주셔서 감사드립니다 :)

그리고 처음에 답해주신 분의 코드가 잘 이해가 안되서요....

제가 해놓은 소스 보여드리고, UI 그려놓은것만 올려볼게요....

위에 코드를 적용시켜 보려 하는데... 이해가 안되네요...

캔버스에 리스너를 다는것 까지는 알겠는데

위에 코드에서 이해가 안되는 부분을 몇가지 말씀드려보면

1. CustomEvent e

CustomEvent라는건 찾아봐도 없는것 같구요...

2.
for(CustomListener l : listeners) {
CustomEvent e = new CustomEvent();
l.execute(e);
}

for 안에 있는게 어떤 의미인지를 모르겠습니다... 처음보는 문법인데요 ㅠ
그리고 l.execute(e)를 하는데, l이 구현되어 있지 않은 인터페이스인데
어떤 동작을 하는지 잘 이해가 안되구요...

3. 각 원이 Multicast에 등록한다고 했는데...
멀티캐스트가 유지하고 있는 리스트에 추가하는것 같은데...
왜 여기서 execute를 구현하는지 잘 이해가 안됩니다.

질문을 써놓고 보니 자바에 대한 이해가 부족하다는 느낌이 많이 드네요... ㅠㅠ

그래도 자바는 약간이나마 안다고 생각했는데 갑갑합니다.... ㅠㅠ

제 소스 붙여 볼테니 도움좀 부탁드립니다.

감사합니다.

import javax.swing.*;
 
import sun.org.mozilla.javascript.internal.ContextFactory.Listener;
 
import java.awt.*;
import java.awt.event.*;
 
public class GraphEditor {
	public static void main(String[] args) {
		_GraphEditor ge = new _GraphEditor();
		ge.canvasPanel.addMouseListener(new MyListener(ge));
		ge.canvasPanel.addMouseMotionListener(new MyListener(ge));
		ge.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		ge.setVisible(true);		
	}
}
 
class MyListener implements MouseListener, MouseMotionListener{
	private static final long serialVersionUID = 1L;
	private _GraphEditor ge;
	public MyListener(_GraphEditor ge){
		this.ge=ge;
	}
 
	public void mouseClicked(java.awt.event.MouseEvent e) {
		if(this.ge.createButton.isSelected()){
			System.out.println("Create Vertex");
			//TODO drawOval and add to List
		}else if(this.ge.connectButton.isSelected()){
			System.out.println("Connect Vertices");
			//TODO drawEdge and add to List
		}else if(this.ge.mergeButton.isSelected()){
			System.out.println("Merge Vertices");
			//TODO select two vertices and merge them into a vertex. maybe redraw
 
		}else{
			System.out.println("Split Vertex");
			//TODO split merged vertex into two vertices. maybe redraw
		}		
	}
	public void mousePressed(java.awt.event.MouseEvent e) {
 
	}
	public void mouseReleased(java.awt.event.MouseEvent e) {
 
	}
	public void mouseEntered(java.awt.event.MouseEvent e) {
 
	}
	public void mouseExited(java.awt.event.MouseEvent e) {
 
	}
	public void mouseDragged(java.awt.event.MouseEvent e) {
		//TODO when selecte mode, move vertex or edge. maybe redraw
		//TODO when merge mode, draw focusbox to choose two vertices. maybe XOR brush
	}
	public void mouseMoved(java.awt.event.MouseEvent e) {
 
	}	
}

==========================
Toward Fully Understanding

댓글 첨부 파일: 
첨부파일 크기
Image icon graph.PNG10.08 KB

//TODO

mykldp의 이미지

1. CustomEvent 는 표준 API에 있는게 아니구요. tyolee83 님께서 직접 정의하신다고 한 이벤트를 그냥 그렇게 쓴겁니다. 의도에 맞게 아무렇게나 만드셔도 관계 없습니다.^^

2. for(Type var : container) 는 자바 5.0 에서 추가된 문법입니다. container 에는 배열 또는 java.util.Iterable 인터페이스를 구현한 객체가 올 수 있습니다. 그러면 그 녀석의 모든 원소들을 차례로 돌면서 for 블럭이 실행됩니다. 예를 들어 String 을 담고 있는 ArrayList list 에 대해서 적용한다치면

for(String s : list) {
	System.out.println(s);
}

는 아래와 동일합니다.
Iterator itr = list.iterator();
while(itr.hasNext()) {
	String s = itr.next();
	System.out.println(s);
}

3. 제가 tyolee83 님께서 하고자하는 바를 제대로 이해했는지 잘 모르겠지만 ^^; 말하자면 이런식입니다.

Canvas 에서 발생한 MouseEvent 를 받아서 처리하기 위해서 canvas 에 MouseListener 를 등록하듯이, 각 원도 Multicaster 가 발생시키는 이벤트를 받기 위해서 Multicaster에 CustomEvent에 대한 리스너를 등록하는겁니다. 보통 Listener pattern 이라고 부르는 패턴이구요. 구현 방식은 Swing 과 조금 다르지만 기본적인 아이디어는 같습니다. 실행 순서를 따지자면 아래와 같지요.

1. 각 원은 Multicaster 에 CustomEvent 에 대한 리스너를 등록한다. 즉, "난 Multicaster 가 발생시키는 이벤트에 관심있다"고 알려주는 겁니다.
2. Canvas 에서 마우스 이벤트가 발생하면 Multicaster가 이벤트를 받는다.
3. Multicaster 는 필요한 정보를 담아서 CustomEvent 객체를 만든다.
4. Multicaster 는 등록된 CustomListener 에게 이벤트를 알린다.(즉, 등록된 각 CustomListener 의 execute 메소드를 실행시킨다.)

"왜 여기서 execute를 구현하는지 잘 이해가 안됩니다." 라고 물으셨는데 execute 구현은 각 CustomListener 가 하는거지 Multicaster 가 하는 것이 아닙니다. CustomListener 의 execute 를 "호출하는" 부분이 Multicaster 에 있을 뿐입니다.

tyolee83의 이미지

자세한 설명 감사드립니다.

설명해 주신 내용이 완벽하게 제가 구현하고자 하는 내용입니다.

그런데 아직 객체지향의 개념이 완벽하지 않아서 확 와닿지가 않네요...

CustomEvent를 어떻게 구현해야 할지 모르겠네요....

이것도 제가 궁금했던 것중에 하나인데,

멀티캐스터가 원들에게 이벤트를 "어떻게" 보내는지가

정말 큰 의문이었습니다.

sendEvent() 이런 API가 있을줄 알고 뒤져봤는데 암만해도 없더군요 ㅠㅠ

그리고 원을 캔버스에 그리는 부분도 넣어야 하는데

이걸 MyListener에 extends JPanel 한 후에 paint() 메소드를 오버라이딩 시켜서 해야 하는지

아니면 vertex 라는 클래스를 별도로 만들어서

거기에 extends JPanel 한 후에 paint() 해야 할지...

(흠 사실 둘다 해봤는데 원이 안나옵니다. 미치겠네요 ㅠㅠ)

상황에 따라서 원들이 캔버스 내에서 움직이는 경우도 있는데...

이런 경우 캔버스로 가능할런지....

답변 정말 감사드리고, 조금만 더 도움 부탁드립니다.
==========================
Toward Fully Understanding

//TODO

mykldp의 이미지

음... 저라면 대충 아래처럼 하겠습니다.^^; 컴파일 안해본 코드이고 기억나는대로 썼으니 정확하지 않습니다. 역시 내용은 전달되리라 믿으면서.. 다른 좋은 방법들도 있겠지만, 뭐 일단 적당히...^^

class Vertex {
	public Vertex() {
		m = new VertexModel();
		v = new VertexView();
	}
 
	getVertexModel()~~
	setVertexModel()~~
	getVertexView()~~
	setVertexView()~~
 
	private VertexModel m;
	private VertexView v;
}
 
class VertexModel {
	getName() ~~
	setName() ~~
 
	private String name;
	//기타 데이터들...
}
 
class VertexView {
	public VertexView(VertexModel v) {
		this.v = v;
	}
 
	public void draw(Graphics2D g) {
		g.drawCircle()
		g.drawText(v.getName());
	}
 
	private VertexModel v;
	//기타 위치나, 크기 등등 "그림"과 관련된 데이터들...
}
 
class GraphCanvas extends Canvas {
	public void paint() {
		for(VertexView v : vertexViewList) {
			v.draw(this.getGraphics());
		}
	}
 
	public void registerVertexView(VertexView v) {
		vertexViewList.add(v);
	}
 
	List vertexViewList = new ArrayList();
}
 
class GraphEditor {
 
	GraphEditor() {
		//일단 GUI 를  구성합니다. 각 요소들을 적절히 배치하고,
		//아래처럼 이벤트에 대한 행동들을 정해줍니다.
 
		canvas.addMouseListener(new MouseListener {
			public void mouseClicked(java.awt.event.MouseEvent e) {
				switch(command) {
					case Command.CREATE:
						Vertex v = new Vertex();
						v.getVertexModel().setName("new vertex");
						vertexList.add(v);
						canvas.registerVertexView(v.getVertexView());
						break;
					case Command.CONNECT:
 
						~~~
 
				}
			});
		}
 
		createButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				command = Command.CTEATE;
			}
		}
 
		connectButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				command = Command.CONNECT;
			}
		}
 
		~~~~
	}
 
	private int command;
	private List vertexList = new ArrayList();
 
	~~
}
 
class Command {
	public static int CREATE = 1;
	public static int CONNECT = 2;
 
	...
}
tyolee83의 이미지

자세한 답변 감사드립니다.

이걸 참고로 해서 한번 다시 달려들어봐야 겠네요.

정말 감사드립니다.

이제 문제없이 해결할 수 있었으면 ㅠㅠ
==========================
Toward Fully Understanding

//TODO

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.