Zaloguj się
Projekty Kategorie Archiwum

"Throwable Events" to stosunkowo nowa technika obsługi zdarzeń w języku Java, która może służyć jako zamiennik starego i niewygodnego systemu "listenerów". Główną zaletą jest większa przejrzystość kodu (nie trzeba dodawać setek addFooListener), oraz łatwość implementacji w programach korzystających z wielu wątków.

Przykładowa implementacja

Klasa Button:

public class Button extends JButton {
	public Button(String text) {
		super(text);
		addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				throw new ClickEvent(e.getSource());
			}
		} );
	}
}

Klasa ClickEvent:

public class ClickEvent extends RuntimeException {
	private Object source;
	public ClickEvent(Object source) {
		this.source = source;
	}
	public Object getSource() { return source; }
}

Przykład użycia

Czytaj dalej...

/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice 
 * is preserved.
 * ====================================================
 */

#include "fdlibm.h"

#ifdef __STDC__
       double __ieee754_hypot(double x, double y)
#else
       double __ieee754_hypot(x,y)
       double x, y;
#endif
{
       double a=x,b=y,t1,t2,y1,y2,w;
       int j,k,ha,hb;

       ha = __HI(x)&0x7fffffff;       /* high word of  x */
       hb = __HI(y)&0x7fffffff;       /* high word of  y */
       if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
       __HI(a) = ha;       /* a <- |a| */
       __HI(b) = hb;       /* b <- |b| */
       if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
       k=0;
       if(ha > 0x5f300000) {       /* a>2**500 */
          if(ha >= 0x7ff00000) {       /* Inf or NaN */
              w = a+b;                     /* for sNaN */
              if(((ha&0xfffff)|__LO(a))==0) w = a;
              if(((hb^0x7ff00000)|__LO(b))==0) w = b;
              return w;
          }
          /* scale a and b by 2**-600 */
          ha -= 0x25800000; hb -= 0x25800000;       k += 600;
          __HI(a) = ha;
          __HI(b) = hb;
       }

Czytaj dalej...

11 marca

JDK7 (build 50) doczekało się nowego API dla plików. Inżynierowie Sun Microsystems ciężko pracowali przez <b>dziesięć</b> lat, ale w końcu udało się!

Teraz można skopiować plik za pomocą <b>jednej</b> linijki kodu...

import java.nio.file.*;
...
Paths.get("foo").copyTo(Paths.get("bar"));
10 marca

ProgressIcon to prosta implementacja javax.swing.Icon, która oprócz zwykłego obrazka ikony, wyświetla również "pasek postępu".

Pobierz

Ikona ProgressIcon umieszczona na przycisku JButton:

Image Hosted by ImageShack.us

Kod powstał w ramach eksperymentów, więc API może być trochę niekompletne ;)

3 grudnia

Całkiem zabawne. Teraz czekam na WolfenKDE ;)

13 listopada

Przed:

...
showClose.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
		JCheckBox source = (JCheckBox)e.getSource();
		closeButton.setVisible(source.isSelected());
	}
} );
...

Po:

...
showClose.onSelect(closeButton, "visible");
...

Jak widać, druga wersja jest znacznie krótsza :) Cała tajemnica tkwi w klasie EventHandler, która tworzy za nas odpowiednie zdarzenia oraz ustawia odpowiednie właściwości obiektu. Prosta implementacja klasy MyCheckBox oraz MyButton wygląda tak:

Czytaj dalej...

Na początku obrazek, żeby było wiadomo o co chodzi:

Free Image Hosting at www.ImageShack.us

Jak widać u góry mamy coś w rodzaju "kart" (JList) z ikonami oraz podpisem. Poniżej znajduje się wybrany panel (Page) z przykładowymi opcjami.

Pozioma lista

Jak powszechnie wiadomo, typowa lista składa się elementów ułożonych pionowo jeden pod drugim. Aby zmienić layout na poziomy, wystarczy ustawić właściwości layoutOrientation oraz visibleRowCount jak poniżej:

pageList = new JList(...
...
pageList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
pageList.setVisibleRowCount(1);

Renderer

Czytaj dalej...

Po JWebPane i JEditorPane przyszła kolej na Mozillę oraz IE ;)

Przykładowy kod

import javax.swing.*;

import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;

public class Test extends JFrame {

public static void main(String... args) {
	SwingUtilities.invokeLater(new Runnable() {
		public void run() {
			NativeInterface.open();
			new Test();
		}
	} );
}

private Test() {
	super("Test");
	setDefaultCloseOperation(EXIT_ON_CLOSE);
	setSize(800, 600);
	setLocationRelativeTo(null);

	JWebBrowser browser = new JWebBrowser();
	browser.navigate("http://jogger.pl");
	add(browser);

	setVisible(true);
}

}

Czytaj dalej...

Jak zrobić poniższy formularz?

Free Image Hosting at www.ImageShack.us

Bardzo prosto..

<EXCEPRT>
import org.makagiga.form.*;
public class Test implements Runnable {
	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Test());
	}
	public void run() {
		LoginForm form = new LoginForm();
		Factory.Content content = Factory.newDialog(null, form);
		if (content.getDialog().exec())
			System.err.printf("user=%s, password=%s, remember=%s\n",
				form.user, form.password, form.remember);
	}
	
	@Form(label="Login")
	static class LoginForm {
		
		@Field(label="Username:", required=true)
		String user;
		
		@Field(label="Password:")
		char[] password;
		
		@Field(label="Remember password", style="color:green; font-size:smaller")
		boolean remember;

	}

}

Analizę działania programu, pozostawiam czytelnikowi jako zadanie domowe ;)

Funkcja DateFormatSymbols.getMonths() zwraca tablicę z nazwami miesięcy. Tablica ta, jak łatwo się domyślić, zawiera 13 miesięcy, gdzie dla większości lokalizacji/krajów ostatnia nazwa miesiąca jest pustym Stringiem...

Z kolei pole Calendar.MONTH, w przeciwieństwie do pola z dniem miesiąca, zaczyna się od zera (0=Styczeń, 1=Luty, etc.). Prawda, że proste.. Na szczeście w JDK 7 chyba już będzie nowe API do obsługi daty, które zastąpi (tu słowo kończące się na "ne") java.util.Date/Calendar :)

26 maja

JWebPane - "Swing compatible WebKit implementation"

To zupełnie nowy komponent bazujący na WebKit. David Qiao na swoim blogu napisał: "This is something Java/Swing community has been crying for years. (...) That’s a lightweighted Swing component for html viewing (or editing)." I wszystko jasne :)

Trochę więcej informacji można znaleźć w PDF-ie z tegoroczego JavaOne.

javax.swing.JLabel i inne

Czytaj dalej...

23 marca

Głupie pytanie! Napisałem to, żeby nauczyć się trochę Scene Graph. A ponieważ przypadkowo wpadło w ręce Phys2D, to połączyłem te dwa API.. Zasady są proste: układamy domek z klocków za pomocą myszy, a potem wszystko rozwalamy :P Dodatkowo można sterować grawitacją, bo kto powiedział, że musi spadać na dół? Przycisk "Reset" usuwa wszystkie klocki.

Uruchom (168KB)

Launch

Jest kilka drobnych błędów:

  • Przeciągnij-i-upuść czasami jest nieprzewidywalne
  • W zależności od komputera może działać za szybko lub za wolno, ale na razie nie chce mi się tego poprawiać ;)
  • Później umieszczę paczkę ze źródłami..

Update - v0.2 :)

  • Ładniejsze kolory
  • Dodana opcja pauzy
  • Sterowanie grawitacją za pomocą klawiszy strzałek
  • Opcjonalne efekty (raczej powolne i z błędami)
  • Teraz powinno też działać z Java 1.5
20 marca

W końcu JDK doczeka się nowego dema dla Swinga. Teraz wszystkie komponenty będą posegregowane według kategorii, co powinno ułatwić zabawę. Najciekawszą rzeczą jest funkcja "Highlight code to", która od razu wyświetla kod źródłowy dla wybranego elementu programu. Na przykład: Chcesz nauczyć się jak zrobić tabelkę przy użyciu JTable? Wystarczy parę kliknięć, Ctrl+C/V i gotowe ;)

Free Image Hosting at www.ImageShack.us

Przy okazji mogliby jeszcze zmienić licencje przykładowych programów, bo wspominanie o "nuclear facility" w aplecie "Kółko i krzyżyk" jest raczej dość zabawne :)

Update

Strona projektu: https://swingset3.dev.java.net/

6 stycznia

Jeśli ktoś jest zainteresowany wersją "przenośną", to może przetestować wersję alpha - download (dla windows). Wystarczy rozpakować i uruchomić. Może komuś się przyda.. Poniżej techniczne bzdury ;)

A cała tajemnica przenośności polega na użyciu innego konstruktora QSettings:

#ifdef KS_PORTABLE
... = new QSettings(QApplication::applicationDirPath() + "\\kshutdown.ini", QSettings::IniFormat);
#else
... = new QSettings();
#endif

17 grudnia
import java.net.*;
import java.util.*;
public class Test {
	public static void main(String[] args) throws MalformedURLException {
		HashSet<URL> set = new HashSet<URL>();
		set.add(new URL("http://jogger.pl"));
		set.add(new URL("http://techblog.pl"));
		set.add(new URL("http://jogger.pl"));
		set.add(new URL("http://google.pl"));
		System.out.println(set.size());
	}
}

Jaką wartość wyświetli println na końcu programu? Jeśli myślisz że 4 lub 3, to się mylisz.. :)

Inne "ciekawostki" można obejrzeć na tej ponad godzinnej prezentacji: Advanced Topics in Programming Languages: Java Puzzlers

Generalnie można to podsumować krótko: Używaj FindBugs, żeby znaleźć wszystkie upierdliwe błędy, których normalnie byś nie zauważył :)

Parę dni temu ujawniono wielki sekret(tm). Chodzi nową i darmową (licencja LGPL) bibliotekę służącą do renderowania plików PDF - PDF Renderer. Pomimo tego, że sama biblioteka jest jeszcze w dość wczesnej (?) fazie rozwoju, to działa bardzo dobrze i szybko ;)

Więc jak użyć to API, żeby wyświetlić plik PDF w Swingu?

Czytaj dalej...

17 września

Na razie zajęło mi to z 5 minut, więc nie należy się spodziewać wielkich rewelacji. Wyświetla się informacja o ładowaniu kernela, wersja systemu, a potem panic ;) Jeśli też chcesz stworzyć swój własny OS, to zerknij na stronę projektu MikeOS (16-bit real mode operating system for x86-compatible PCs)..

Screenshot

Free Image Hosting at www.ImageShack.us

KMail potrafi zapamiętywać podane hasła w pliku ~/.kde/share/config/kmailrc. Hasła "szyfrowane" są tak, żeby na pierwszy rzut oka, nie można ich było odczytać. Zanim takie hasło zostanie zapisane na dysku, zostaniemy ostrzeżeni mniej więcej takim komunikatem: The password is stored in an obfuscated format, but should not be considered secure (...)

Tak więc spróbujmy wyświetlić wszystkie hasła KMail... Do tego, z pozoru trudnego zadania, wystarczy prosty skrypt, oraz trochę JavaScriptu (bo nie wiedziałem jak pobrać te wartości Unicode). Sam algorytm szyfrowania znalazłem w Google ;)

Czytaj dalej...

25 lipca

Dodanie obsługi OpenGL/3D za pomocą JOGL jest proste :) Wystarczy utworzyć obiekt GLCanvas, na którym wszystko jest rysowane, a następnie dodać GLEventListener. Z GLEventListener interesują nas głównie metody init, display i reshape.

  • init - wywoływane przy starcie programu

  • display - tutaj rysujemy naszego Dooma IV ;)

  • reshape - wywoływane przy starcie programu, oraz gdy zmieni się rozmiar okna

Przykładowy program

Free Image Hosting at www.ImageShack.us

Czytaj dalej...

3 marca

Update: Zobacz też Projekt xswingx

Wyobraźmy sobie, że mamy JPanel, na którym znajdule się pole tekstowe i przycisk (obrazek 1). Nie wygląda to zbyt ładnie :-)

before

Na drugim screenshocie jest już znacznie lepiej. Ale jak wstawić przycisk do pola tekstowego?

after

Czytaj dalej...

2 sierpnia

Wyobraźmy sobie, że mamy jakąś osobę, której chcemy wręczyć łapówkę. Niestety nasza klasa definiująca osobę nie posiada funkcji służącej do wręczania łapówek:

public class Osoba { }

Rozbudujmy więc naszą klasę (polskie znaki zostały użyte w celu podniesienia przejrzystości kodu):

public class Osoba {
  void dajWŁapę(int kwota) { }
}

Okej... Chwilkę, przecież nie wszystkie osoby muszą być od razu skorumpowne...

Tada! Tak już lepiej. No nie zupełnie... Rokita* mógłby się obrazić (*edit: pisane w 2005 roku...).

public class Polityk extends Osoba {
  void dajWŁapę(int kwota) { }
}

Teraz chyba wszystko jest już w porządku:

public class SkorumpowanyPolityk extends Polityk {
  void dajWŁapę(int kwota) { }
}

Taaa... A co z urzędnikami, lekarzami, etc? Wszyscy biorą w ten sam sposób. Trzeba zdefiniować wspólną metodę (interfejs). Oto nasz "sposób" na wręczanie łapówek dla wszystkich skorumpowanych osób:

public interface Skorumpowany {
  void dajWŁapę(int kwota);
}

1. Teraz możemy wziąć dowolną osobę:
Osoba jakaśOsoba = ...

2. Sprawdzić, czy jest skorumpowana:
if (jakaśOsoba instanceof Skorumpowany)

3. I w końcu wręczyć łapówkę:
Skorumpowany.class.cast(jakaśOsoba).dajWŁapę(1000); // Java 5.0 i nowsza
((Skorumpowany)jakaśOsoba).dajWŁapę(1000); // Java starsza niż 5.0

4. A nasza nowa klasa opisująca skorumpowanego polityka, wygląda tak:

public class SkorumpowanyPolityk extends Polityk implements Skorumpowany {
  void dajWŁapę(int kwota) { }
}

A to przykładowy algorytm zamykający wszystkie skorumpowane osoby w Polsce ;-)

for (Osoba osoba : wszyscyMieszkańcyPolski) {
  if ((osoba instanceof Skorumpowany) && !(osoba instanceof Immunitet))
    doPaki(osoba);
}

Nowsze wpisy >

Kategorie

Ewolucja Internetu 8 | Fail 40 | Gry 46 | Humor 129 | Idiotyzm 50 | Java 110 | KDE 85 | KShutDown 22 | Linux 84 | Makagiga 58 Muzeum 3 | Ogólne 819 | Polityka 76 | Programowanie 51 | Reklamy 4 | Techblog 19 | Teorie Spiskowe 12 | TV 59 | UI 9 | Użyteczność 30 | WWW 90 | Wyrwane z Kontekstu 34 | X Files 14

Archiwum

Maj 2012 | Kwiecień 2012 | Marzec 2012 | Luty 2012 | Styczeń 2012 | Grudzień 2011 | Listopad 2011 | Październik 2011 | Wrzesień 2011 | Sierpień 2011 | Lipiec 2011 | Czerwiec 2011 | Maj 2011 | Kwiecień 2011 | Styczeń 2011 | Listopad 2010 | Październik 2010 | Wrzesień 2010 | Sierpień 2010 | Lipiec 2010 | Czerwiec 2010 | Kwiecień 2010 | Marzec 2010 | Luty 2010 | Styczeń 2010 | Grudzień 2009 | Listopad 2009 | Październik 2009 | Wrzesień 2009 | Sierpień 2009 | Lipiec 2009 | Czerwiec 2009 | Maj 2009 | Kwiecień 2009 | Marzec 2009 | Styczeń 2009 | Grudzień 2008 | Listopad 2008 | Październik 2008 | Wrzesień 2008 | Sierpień 2008 | Lipiec 2008 | Czerwiec 2008 | Maj 2008 | Kwiecień 2008 | Marzec 2008 | Luty 2008 | Styczeń 2008 | Grudzień 2007 | Listopad 2007 | Październik 2007 | Wrzesień 2007 | Sierpień 2007 | Lipiec 2007 | Czerwiec 2007 | Maj 2007 | Kwiecień 2007 | Marzec 2007 | Luty 2007 | Styczeń 2007 | Grudzień 2006 | Listopad 2006 | Październik 2006 | Wrzesień 2006 | Sierpień 2006 | Lipiec 2006 | Czerwiec 2006 | Maj 2006 | Kwiecień 2006 | Marzec 2006 | Luty 2006 | Styczeń 2006 | Grudzień 2005 | Listopad 2005 | Październik 2005 | Wrzesień 2005 | Sierpień 2005 | Lipiec 2005 | Czerwiec 2005 | Maj 2005 | Kwiecień 2005 | Marzec 2005 | Luty 2005 | Styczeń 2005