View Full Version : Cercasi programmtore java per mini-progetto
simone.o
30-10-2006, 20:50
Buonasera,
Sto cercando per un amico un programmatore java che sviluppi una piccola applicazione, ovviamente in java, per un mini-progetto.
Il progetto consiste, a grandi linee, nel fare un applicazione con cui sia possibile una semplice operazione di disegno. Mi spiego.
Il mouse fa da matita e sull'area sensibile dell'applicazione viene tracciato un segno. Nulla di più. La scadenza è lontana! E' necessario utilizzare le due classi specifiche per il disegno e, sopratutto, che sia semplice da comprendere.
Chi vuole, ovviamente pagato, può contattarmi tramite E-MAIL per mettersi d'accordo sui dettagli del progetto e il pagamento.
Un saluto a tutti,
Simone
PS. x i mod, non so se è la sezione giusta, in caso mi scuso per il disagio
franksisca
30-10-2006, 22:57
la sezione è giusta, è sbagliato il modo di chiedere le cose......
Digli al tuo amico di iniziare l'applicazione, e se ha qualche problemino, di postarlo e se riusciremo insieme cercheremo di risolverlo.
Non per cattiveria, ma almeno io non ho il tempo per la tesi, figurati per fare il progettino al tuo amico, mentre una dritti mi ruberebbe un solo secondo;)
Se si tratta di una traccia col mouse è di una semplicità tale che spero nessuno vorrà mai farsi pagare per farlo. Ti incollo un esempio che è un po' troppo per un semplice tratto del mouse su un componente e un troppo poco per un disegno stilizzato ma contiene le basi per l'uno e per l'altro.
Nelle mie intenzioni è talmente elementare (nel senso che sono evidenti gli elementi) che non dovrebbero esserci problemi nel fare qualcosa di più o di meno.
Per poterlo copiare più facilmente sul forum ho scritto tutto usando un'unità di compilazione (Main.java). Evidenzio in grassetto i nomi dei vari tipi creati, che sarebbero tutti pubblici se un'unità di compilazione javac potesse contenere più di un tipo pubblico.
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
/** Da qui parte tutto */
public class Main {
public static void main(String[] args) {
new Schizzo().apriFinestraPrincipale();
}
}
/** Una traccia è qualcosa che disegna usando
un Graphics2D e un rettangolo */
interface Traccia {
/** Applica questa traccia al contesto grafico g
nell'area in argomento */
void disegna(Graphics2D g, Rectangle area);
}
/** Uno strumento */
interface Strumento extends MouseListener, MouseMotionListener {
/** Imposta la tela a cui è applicato lo strumento */
void collegaTela(Tela t);
/** Disegna la traccia di quello che lo strumento sta facendo */
void disegnaTracciaInCostruzione(Graphics2D g, Rectangle areaDisegno);
}
/** Una tela da disegno */
interface Tela {
/** Restituisce lo strumento correntemente applicato alla tela */
Strumento getStrumentoCorrente();
/** Imposta lo strumento applicato alla tela */
void impostaStrumento(Strumento s);
/** Aggiunge una traccia alla tela */
void aggiungiTraccia(Traccia t);
/** Elimina una traccia dalla tela */
void eliminaTraccia(Traccia t);
/** Restituisce tutte le tracce presenti nella tela */
Collection<Traccia> getTracce();
/** Aggiona la tela */
void aggiorna();
/** Restituisce il componente Swing che
proietta la tela */
JComponent getSchermo();
}
/** Una traccia che colora un'area usando una tinta */
class Sfondo implements Traccia {
/** la tinta usata per colorare */
private Paint colore;
/** Inizializza lo sfondo corrente usando la tinta
in argomento */
public Sfondo(Paint colore) {
this.colore = colore;
}
/** Applica lo sfondo */
public void disegna(Graphics2D g, Rectangle areaDisegno) {
g.setPaint(colore);
g.fill(areaDisegno);
}
}
/** La traccia di una matita è... una linea nera. */
class TracciaMatita implements Traccia {
/* GeneralPath è la versione Java2D di un percorso
irregolare fatto di tanti segmenti, retti o curvi */
private GeneralPath percorso;
/** Inizializza la traccia corrente usando il percorso in
argomento */
public TracciaMatita(GeneralPath percorso) {
/* clona il percorso onde evitare che questa traccia
subisca modifiche per mutazioni dello strumento che
l'abbia creata */
this.percorso = (GeneralPath)percorso.clone();
}
/** Applica la traccia */
public void disegna(Graphics2D g, Rectangle area) {
g.setColor(Color.BLACK);
/* Graphics2D.draw(Shape), GeneralPath è uno Shape */
g.draw(percorso);
}
}
/** Strumento che genera una TracciaMatita su una Tela */
class StrumentoMatita extends MouseInputAdapter implements Strumento {
/* Tela a cui è applicato questo strumento */
private Tela tela;
/* Percorso temporaneo usato durante la creazione della traccia.
L'utente trascina il mouse e aggiunge punti a questo GeneralPath.
Questo GeneralPath è usato per proiettare sulla tela la traccia
che si sta disegnando. Terminato il disegno (rilascio del mouse)
questo GeneralPath è usato per costruire la traccia definitiva
che è poi aggiunga alla tela corrente. */
private GeneralPath percorso = new GeneralPath();
/* Questo valore è usato come un interruttore per stabilire se
questo strumento abbia o non abbia una traccia temporanea da
proiettare sulla tela durante l'operazione di disegno */
private boolean inCostruzione = false;
/** Collega questo strumento alla tela t */
public void collegaTela(Tela t) {
this.tela = t;
}
/** Disegna la traccia in costruzione */
public void disegnaTracciaInCostruzione(Graphics2D g, Rectangle area) {
/* Se stiamo disegnando qualcosa... */
if(inCostruzione) {
/* riproduce su g la traccia temporanea */
g.setColor(Color.BLACK);
g.draw(percorso);
}
}
public void mousePressed(MouseEvent e) {
/* Quando si preme il mouse, il punto di pressione
diventa il primo punto della traccia temporanea */
iniziaLinea(e.getPoint());
}
public void mouseDragged(MouseEvent e) {
/* Durante il trascinamento vengono aggiungi i punti
in cui si trova il mouse, uno alla volta, alla
traccia temporanea */
continuaLinea(e.getPoint());
}
public void mouseReleased(MouseEvent e) {
/* Qui termina la costruzione della traccia temporanea */
terminaLinea(e.getPoint());
}
/* Invocato alla pressione del mouse sul componente Swing
della tela da disegno. p è il punto in cui è stato premuto
il mouse */
private void iniziaLinea(Point p) {
/* azzera tutti il contenuto della traccia temporanea, onde
evitare l'accumulo dei punti tra la traccia prodotta in
precedenza e quella che si sta iniziando a produrre */
percorso.reset();
/* Un GeneralPath "azzerato" deve avere come prima "istruzione"
un moveTo che è come dire "inizia da qui..." */
percorso.moveTo(p.x, p.y);
/* Impostando a true questo valore lo strumento disegna
la traccia temporanea quando "qualcuno" lo richiesta attraverso
il metodo disegnaTracciaInCostruzione. Questo qualcuno è
la tela */
inCostruzione = true;
/* Invocando l'aggiornamento della tela la tela, tra le altre
cose, invocherà il metodo disegnaTracciaInCostruzione. Questo
comporta la proiezione sulla tella della traccia in costruzione */
aggiornaTela();
}
private void continuaLinea(Point p) {
/* Aggiunge un segmento al percorso temporaneo */
percorso.lineTo(p.x, p.y);
/* Invocando l'aggiornamento della tela la tela, tra le altre
cose, invocherà il metodo disegnaTracciaInCostruzione. Questo
comporta la proiezione sulla tella della traccia in costruzione,
che ora contiene un punto in più */
aggiornaTela();
}
private void terminaLinea(Point p) {
/* Avendo terminato il disegno, la traccia temporanea non dovrà
più essere disegnata se qualcuno (la tela) lo richieda */
inCostruzione = false;
/* Ammesso che una tela esista...per sicurezza :D */
if(tela != null) {
/* Con il percorso temporaneo, che ha immagazzinato tutti i
punti della linea che si vuole aggiungere alla tela, crea una
Traccia da aggiungere alla tela */
Traccia prodotto = new TracciaMatita(percorso);
/* aggiunge la nuova traccia alla tela */
tela.aggiungiTraccia(prodotto);
/* aggiorna la tela. La tela invocherà, tra l'altro, il
metodo disegnaTracciaInCostruzione ma questo strumento,
rilevando che il valore "inCostruzione" è false, non
disegnerà un bel niente (perchè non c'è più alcuna traccia
in costruzione) */
aggiornaTela();
}
}
/* Se c'è una tela collegata, chiede alla tela di aggiornarsi: o perchè
è stato aggiornato il percorso che fa vedere all'utente cosa sta
disegnando o perchè l'utente ha finito di disegnare è questo strumento
ha rifilato alla tela una nuova traccia */
private void aggiornaTela() {
if(tela != null) {
tela.aggiorna();
}
}
}
/** Una tela da disegno */
class TelaBase implements Tela {
/* Una lista per conservare l'insieme di tutte le tracce aggiunte
a questa tela, in ordine di inserimento */
private ArrayList<Traccia> listaTracce = new ArrayList<Traccia>();
/* Questo serve per poter riprodurre un disegno composto da una
quantità tale di tracce da mettere in crisi la riproduzione se
questa fosse semplicemente affidata al disegno di tutte le tracce
contenute in listaTracce, una per una */
private BufferedImage bufferDisegno;
/* L'area di disegno serve per quegli strumenti e quelle tracce
a cui non basti
avere un appliglio su cui proiettare qualcosa (per questo basta
Graphics2D) ma necessitino anche di sapere "fin dove possono
disegnare". Ad esempio, e per puro caso :D, la traccia Sfondo */
private Rectangle areaDisegno;
/* Questo è il componente Swing il cui metodo paintComponent con
annesso Graphics2D è usato per visualizzare concretamente il
disegno */
private JPanel telaDisegno = new JPanel() {
public void addNotify() {
/* Questo metodo è invocato dal framework Swing
quando questo componente è connesso ad un
albero di visualizzazione. */
super.addNotify();
/* A noi ce frega perchè è dalla ricezione di
questa notifica che il metodo getGraphicsConfiguration
restituisce qualcosa di diverso da null. Vedere
creaBufferDisegno per sapere cosa facciamo con
un GraphicsConfiguration */
creaBufferDisegno(getGraphicsConfiguration());
}
public void paintComponent(Graphics graphics) {
/* Le rotelle e gli ingranaggi di Swing causano
l'invocazione di questo metodo paintComponent per
disegnare il contenuto del componente. */
Graphics2D g = (Graphics2D)graphics;
applicaBuffer(g);
applicaStrumento(g);
}
};
/* In questo pannello è infilata la tela qui sopra. Uso un
due contenitori per poter centrare la tela nella finestra. */
private JPanel contenitoreTela;
/* Riferimento allo strumento corrente usato per disegnare */
private Strumento strumentoCorrente;
/* Altezza e larghezza del disegno */
private Dimension dimensioniTela;
/* Questo interruttore serve per stabilire se l'immagine usata
per rappresentare tutte le linee contenute nella tela debba
essere rigenerata. Intendo per rigenerazione la cancellazione
di tutti i pixel e l'applicazione dell'intera serie di
tracce presenti sulla tela */
private boolean rigeneraBuffer = false;
/** Inizializza una tela di larghezza e altezza pari ai
valori in argomento */
public TelaBase(int altezza, int larghezza) {
/* conserva altezza e larghezza in dimensioniTela per
poter successivamente creare un buffer delle giuste
dimensioni */
dimensioniTela = new Dimension(altezza, larghezza);
/* Stabilisco che il componente Swing "telaDisegno"
abbia una dimensione minima e una dimensione
preferita pari alla grandezza del disegno */
telaDisegno.setPreferredSize(dimensioniTela);
telaDisegno.setMinimumSize(dimensioniTela);
/* creo il rettangolo di dimensioni pari alla
superficie da disegno. Questo rettangolo è poi
passato alle varie tracce quando sia richiesta
la loro proiezione attraverso il metodo
disegna(Graphics, Rectangle) */
areaDisegno = new Rectangle(0, 0, altezza, larghezza);
/* Applico questo layout manager al contenitore
della tela. Il possesso da parte della tela di una
dimensione minima pari alla dimensione preferita unito
al particolare significato di alcuni valori predefiniti
e non alterati di GridBagConstraints produce la
collocazione della tela al centro del contenitore
intermedio */
GridBagLayout layout = new GridBagLayout();
GridBagConstraints lim = new GridBagConstraints();
lim.gridx = lim.gridy = 0;
layout.setConstraints(telaDisegno, lim);
contenitoreTela = new JPanel(layout);
contenitoreTela.add(telaDisegno);
}
/** Restituisce lo strumento correntemente usato per questa
tela base */
public Strumento getStrumentoCorrente() {
return strumentoCorrente;
}
/** Imposta lo strumento correntemente applicato a questa
tela base */
public void impostaStrumento(Strumento s) {
/* Prima di connettere un nuovo
MouseListener-MouseMotionListener si accerta di aver rimosso
il precedente. Ciò impedisce, soprattutto, che l'applicazione
plurima di uno stesso strumento causi la gestione multipla
di uno stesso evendo del mouse */
if(strumentoCorrente != null) {
telaDisegno.removeMouseListener(strumentoCorrente);
telaDisegno.removeMouseMotionListener(strumentoCorrente);
}
strumentoCorrente = s;
/* L'invocazione di questo metodo fa sì che lo strumento
sia in grado di affidare a questa tela (this) la traccia
creata al termine dell'interazione */
strumentoCorrente.collegaTela(this);
/* L'invocazione di questi metodi, definiti nel framework
Swing, fa sì che gli eventi del mouse (o di movimento
del mouse) intercettati dal componente "telaDisegno" (un
JPanel Swing) sia inviati per la gestione al MouseListener
strumentoCorrente ed al MouseMotionListener strumentoCorrente */
telaDisegno.addMouseListener(strumentoCorrente);
telaDisegno.addMouseMotionListener(strumentoCorrente);
}
/** Restituisce il componente Swing che ingloba la tela
da disegno */
public JComponent getSchermo() {
return contenitoreTela;
}
/** Aggiorna il contenuto della tela da disegno */
public void aggiorna() {
/* Se occorre "rigenerare il buffer"... */
if(rigeneraBuffer) {
/* Disegna sull'immagine bufferDisegno un rettangolo
nero grande quanto l'immagine (a coprire tutto ciò che
è stato precedentemente disegnato su questa immagine) */
Graphics2D g = (Graphics2D)bufferDisegno.getGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, bufferDisegno.getWidth(), bufferDisegno.getHeight());
/* Disegna, una per una, tutte le tracce contenute in
questa tela da disegno sull'immagine bufferDisegno */
for(Traccia t : listaTracce) {
t.disegna(g, areaDisegno);
}
rigeneraBuffer = false;
}
/* Chiede al framework di ridisegnare il componente "telaDisegno".
Questo causa, per vie traverse, l'invocazione del metodo
paintComponent del JPanel telaDisegno */
telaDisegno.repaint();
}
/** Aggiunge una Traccia alla tela */
public void aggiungiTraccia(Traccia t) {
/* Accoda la Traccia t alla lista delle tracce */
listaTracce.add(t);
/* Se il bufferDisegno è stato creato... */
if(bufferDisegno != null) {
/* Disegna sul buffer questa nuova traccia */
t.disegna((Graphics2D)bufferDisegno.getGraphics(), areaDisegno);
}
}
/** Elimina la traccia t dalla tela */
public void eliminaTraccia(Traccia t) {
/* L'eliminazione richiede che il buffer sia rigenerato */
rigeneraBuffer = true;
listaTracce.remove(t);
}
/** Restituisce l'insieme di tracce contenute in questa Tela */
public Collection<Traccia> getTracce() {
return listaTracce;
}
/* Crea l'immagine che conterrà il disegno di tutte le tracce
già inserite in questa Tela. L'immagine ha lo scopo di evitare
che il metodo paintComponent di telaDisegno debba disegnare
tutte le linee contenute nella tela, una per volta. Con un
buffer ogni paintComponent richiede semplicemente che la
superficie buffer sia copiata sulla superficie occupata
dal componente Swing telaDisegno */
private void creaBufferDisegno(GraphicsConfiguration cfg) {
/* Crea un'immagine opaca di un formato massimamente compatibile
con il formato nativo della piattaforma. Questo annulla o riduce
la necessità di operare una conversione di formato quando
la superficie debba essere proiettata sullo schermo. */
bufferDisegno = cfg.createCompatibleImage(dimensioniTela.width, dimensioniTela.height);
/* Ottenuta l'immagine disegna su questa tutte le tracce già
presenti nella tela */
Graphics2D g = bufferDisegno.createGraphics();
for(Traccia t : listaTracce) {
t.disegna(g, areaDisegno);
}
}
/* Disegna la superficie bufferDisegno usando il contesto
grafico in argomento (proveniente da telaDisegno) */
private void applicaBuffer(Graphics2D graphics) {
graphics.drawImage(bufferDisegno, 0, 0, null);
}
/* Disegna la traccia dello strumento corrente usando il contesto
grafico in argomento (proveniente da telaDisegno) */
private void applicaStrumento(Graphics2D graphics) {
strumentoCorrente.disegnaTracciaInCostruzione(graphics, areaDisegno);
}
}
/** Gestisce la finestra principale dell'applicazione */
class Schizzo {
/* Finestra principale dell'applicazione */
private JFrame finestra = new JFrame("Schizzo");
/* Dichiara e inizializza una Tela di tipo TelaBase
di 400x400 pixel */
private Tela tela = new TelaBase(400, 400);
/* Ascoltatore degli eventi che sarà associato ai
pulsanti della barra dei menu */
private ActionListener controlloMenu = new ActionListener() {
public void actionPerformed(ActionEvent e) {
/* Se il controllo che ha generato un evento ActionEvent
ha come "etichetta di azione" la stringa "Cancella"... */
if(e.getActionCommand().equals("Cancella")) {
/* Invoca il metodo cancella di questo Schizzo */
cancella();
}
}
};
/** Inizializza un'istanza di Schizzo */
public Schizzo() {
/* Barra dei menu che sarà inserita nella finestra
"finestra" */
JMenuBar menuBar = new JMenuBar();
/* Menu di etichetta "Disegno" inserito nella barra
dei menu */
JMenu menu = menuBar.add(new JMenu("Disegno"));
/* Aggiunge al menu un controllo di etichetta (sia
grafica che d'azione) "Cancella" e registra per questo
controllo l'ascolatore di eventi Action "controlloMenu".
Quando il pulsante "Cancella" sarà premuto, sarà
invocato il metodo "actionPerformed" di controlloMenu
e l'evento ActionEvent passato a questo metodo avrà
per actionCommand la stringa "Cancella" */
menu.add("Cancella").addActionListener(controlloMenu);
/* Inserisce nella finestra la barra dei menu "menuBar",
con relativi menu e controlli */
finestra.setJMenuBar(menuBar);
/* Quando l'utente preme sulla "x" per chiudere la
finestra, la finestra reagirà usando un comportamento
standard (DISPOSE_ON_CLOSE) che causerà l'invocazione
del metodo dispose() del JFrame "finestra" */
finestra.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
/* Aggiunge al pannello del contenuto della finestra,
che usa un layout manager BorderLayout, il componente
Swing in cui è proiettato il disegno della tela */
finestra.add(tela.getSchermo(), BorderLayout.CENTER);
/* Crea una traccia "Sfondo", bianca, e la aggiunge alla
tela */
tela.aggiungiTraccia(new Sfondo(Color.WHITE));
/* Imposta per la tela uno strumento... be', dell'unico
tipo esistente, StrumentoMatita */
tela.impostaStrumento(new StrumentoMatita());
}
/** Azzera il contenuto della tela */
public void cancella() {
/* Prende tutte le tracce contenute nella tela...*/
ArrayList<Traccia> tracce = new ArrayList<Traccia>();
tracce.addAll(tela.getTracce());
/* e le elimina, una per volta (l'unico modo per
farlo visti i comportamenti di cui ho dotato Tela */
for(Traccia t : tracce) {
tela.eliminaTraccia(t);
}
/* Aggiunge alla tela uno sfondo bianco */
tela.aggiungiTraccia(new Sfondo(Color.WHITE));
/* Chiede alla tela di aggiornarsi. La tela
chiederà a Swing di ridisegnare il componente
che proietta le tracce, alla fine della fiera
ci sarà un bel quadratone bianco sullo schermo */
tela.aggiorna();
}
/** Apre sullo schermo la finestra principale tenendo
conto della possibilità che questo metodo sia invocato
ad opera di un Thread diverso dall'AWT Event Dispatcher */
public void apriFinestraPrincipale() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
/* Chiede alla finestra di assumere le dimensioni
minime sufficiente affinchè tutto ciò che contiene
sia proiettato secondo le sue dimensioni preferite
o le dimensioni altrimenti stabilite dai diversi
layout manager */
finestra.pack();
/* rende la finestra visibile */
finestra.setVisible(true);
}
});
}
}
Free/Sbin
31-10-2006, 23:23
la sezione è giusta, è sbagliato il modo di chiedere le cose......
Digli al tuo amico di iniziare l'applicazione, e se ha qualche problemino, di postarlo e se riusciremo insieme cercheremo di risolverlo.
Non per cattiveria, ma almeno io non ho il tempo per la tesi, figurati per fare il progettino al tuo amico, mentre una dritti mi ruberebbe un solo secondo;)
visto che la persona a cui serve è un amico in comune...se avessi letto TUTTO il post ti saresti accorto che veniva garantito un compenso...quindi la modalità è più che corretta in quanto si offre un lavoretto e non si chiede aiuto da 0
franksisca
01-11-2006, 11:50
visto che la persona a cui serve è un amico in comune...se avessi letto TUTTO il post ti saresti accorto che veniva garantito un compenso...quindi la modalità è più che corretta in quanto si offre un lavoretto e non si chiede aiuto da 0
ok, mi sarà sfuggito, ma adesso mi chiedo..... chi sei e chi è l'amico :confused: :confused: :confused:
Free/Sbin
01-11-2006, 11:53
simone è un mio amico e l'amica è un nostro amico comune del liceo
Frank1962
03-11-2006, 10:14
Se si tratta di una traccia col mouse è di una semplicità tale che spero nessuno vorrà mai farsi pagare per farlo. Ti incollo un esempio che è un po' troppo per .....
...ma sei il pgi che una volta postava su mokabyte e, ancor più lontano nel tempo, che postava anche qua su hwupgrade? :)
...ma sei il pgi che una volta postava su mokabyte e, ancor più lontano nel tempo, che postava anche qua su hwupgrade? :)
sai com'è, il lupo perde il pelo... :D
Frank1962
04-11-2006, 00:41
sai com'è, il lupo perde il pelo... :D
allora meriti un bentornato dal cuore! ;)
Andrea16v
04-11-2006, 10:57
Se si tratta di una traccia col mouse è di una semplicità tale che spero nessuno vorrà mai farsi pagare per farlo. Ti incollo un esempio (...)
Scusami, una domanda dal cuore, ma quanto impieghi a scrivere una bozza di programma tipo questo? (alla faccia della bozza) a me sarebbe necessaria almeno una settimana.. :p
Direi anche più di una settimana. Ma la questione "disegno" mi ha sempre incuriosito e, in questo caso, non ho fatto altro che riassumere uno tra i miliardi di esperimenti che avevo già fatto (e mai concluso) sul tema. Ho barato? :D
Andrea16v
04-11-2006, 18:47
Direi anche più di una settimana. Ma la questione "disegno" mi ha sempre incuriosito e, in questo caso, non ho fatto altro che riassumere uno tra i miliardi di esperimenti che avevo già fatto (e mai concluso) sul tema. Ho barato? :D
Ben vengano le persone che barano come te.. :) :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.