天天冒出一堆新的東西!讓人不知所措。
舉個例子:jquery - angular - react - vue
這語言真的有毒。
如今的硬件,恐怕在瀏覽器中實現強類型語言JAVA來作為腳本語言都不比JS弱吧,哎真替applet感到冤枉。
老夫一直就覺得,瀏覽器一直是一個很奇葩的東西,HTML+CSS+JS本身,難道不能發明一種語言通過HTTP傳輸,然后直接調用OS級別的UI來渲染不就完了嗎?
網頁能實現的界面,我不信用操作系統的UI組件做不出來。
posted @
2018-04-01 00:19 West Farmer 閱讀(170) |
評論 (0) |
編輯 收藏
原文地址:
https://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
正則表達式中,
\A是指一個字符串的開頭,可能大家用慣了
^,而忽略了這個
\A, 但是^其實是指一行的開始,而不管一個字符串里面包含多少行,\A都只匹配第一行的開頭。
那么我們可以用\A做點什么呢?,看下面這個例子:
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
相信大家都看懂了,用
\A作為分隔符,那么得到的當然就只有一個token,那就是整個字符串了。再配合Scanner,就輕易的將一個輸入流轉換為一個字符串了。
注意當需要做編碼轉換時,Scanner是有支持編碼參數的構造方法的。
posted @
2013-11-28 09:38 West Farmer 閱讀(1015) |
評論 (0) |
編輯 收藏
摘要: Gson is library created by google guys, it is used for java bean to json serialization/deserialization. Gson can serialize any java bean, collection, map to json, and don't need to care about the...
閱讀全文
posted @
2013-11-22 19:22 West Farmer 閱讀(5323) |
評論 (3) |
編輯 收藏
If we observe a property of SWT controls, and bind it to another observable value, you must take care of those method calls which will change the property indirectly.for example, we have a Combo whose "text" property is bound to a bean's "name" property like this:
IObservableValue nameObservable = BeansObservables.observeDetailValue(obserabedDriverProfile, "name", String.class);
ISWTObservableValue nameComboObservable = SWTObservables.observeText(driverClassCombo);
bindingContext.bindValue(nameComboObservable , nameObservable, new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE), null);
The variable "
obserabedDriverProfile" is a observed selection in a ListViewer, it's in a master-detail scenario. If we add some code like this:
obserabedDriverProfile.addValueChangeListener(new IValueChangeListener(){
@Override
public void handleValueChange(ValueChangeEvent event) {
DriverProfile dp = (DriverProfile)event.diff.getNewValue();
driverClassCombo.removeAll();
driverClassCombo.add(dp.getName();
driverClassCombo.setText(driverClassCombo.getItem(0));
}
});
every time you change the selection in the ListViewer, the selected bean's "name" property will be set to a empty string. Why? The
removeAll method of Combo will clear it's text, and combo's "text" property is bound to selected bean's "name" property. So, the right way is:
obserabedDriverProfile.addValueChangeListener(new IValueChangeListener(){
@Override
public void handleValueChange(ValueChangeEvent event) {
DriverProfile dp = (DriverProfile)event.diff.getNewValue();
String name = dp.getName;
driverClassCombo.removeAll();
driverClassCombo.add(name);
driverClassCombo.setText(driverClassCombo.getItem(0));
}
});
posted @
2013-04-14 15:24 West Farmer 閱讀(251) |
評論 (0) |
編輯 收藏
本文用英文寫的,主要是考慮到本文分享的內容即使在google上也搜索不到(至少我是沒有搜索到)。
My English is at a very low level, don't care about this fact, just focus on the idea shared here.
The idea comes from the source code of
ConfigurationElement which is located in package
org.eclipse.core.internal.registry, If you read through the source code, you can also get it. But I found there is no documentation about this topic, so I wrote this.
Sometimes we need to contribute java class to a extension point. And we can use
ConfigurationElement#
createExecutableExtension(String attributeName) to create an instance of it, if such a class is just a normal class, eclipse will call
class#newInstance(). But there is obvious restriction for using this approach, can't pass parameter in to create instance for example.
There are three different way how eclipse create instance of your class.
- normal, call class#newInstance()
- if your calss implements IExecutableExtension interface, IExecutableExtension#setInitializationData(IConfigurationElement config, String propertyName, Object data) will be called on the instance returned by class#newInstance()
- if your calss implements IExecutableExtensionFactory interface, IExecutableExtensionFactory#create() will be called
When you use the second method or the third method, you can
pass in parameters, check the source code of
ConfigurationElement, you will know how to do that. :D forgive me, I'm lazy.
posted @
2012-04-15 16:33 West Farmer 閱讀(329) |
評論 (0) |
編輯 收藏
SWT的Table不夠強大,而且似乎有嚴重的性能問題。(貌似是調用OS的實現,但是在win7上面跑卻非常慢,奇特!本地的性能不如虛擬機上跑的Swing)
好在SWT中可以嵌入AWT。
反正本人以前沒有過多Swing的經驗,但是在試玩了JTable之后發現確實很強大。
對于有興趣的讀者可以試一下,本文將分享如何使得JTable與JFace Data Binding Framework(下文中簡稱JDBF)一起協同工作。
通常像Table和List這種UI組件,展現的都是一個對象集合。JDBF 則為我們處理對象集合和UI界面的同步的問題。以List為例子,在Java中有java.util.List,而JFDB則提供了相應的
ObservableList類,這個類Wrap一個java.util.List,當你對其進行增刪改時,與其綁定的UI組件會自動得到同步。但是ObservableList 的實現有個很大的問題就是對其的訪問只限于其所屬的Realm,這個Realm說白了就是SWT的UI線程,而當我們在SWT中嵌入AWT時,其中的AWT界面是跑在其自身的線程里面的。所以想要讓JTable與JFace Data Binding Framework(下文中簡稱JDBF)一起協同工作還要解決多線程的問題。廢話不多說了,直接上菜:
public class DOTableModel extends AbstractTableModel { /**
* the ObservableList instance to be shared with
*/
private ObservableList list;
private volatile Integer rowCount = null;
private volatile DOModel object;;
private final Object lock = new Object();
private static final long serialVersionUID = -8377145381412656796L;
public DOTableModel(ObservableList list){
this.list = list;
this.list.addListChangeListener(new IListChangeListener(){
@Override
public void handleListChange(ListChangeEvent event) {
for(ListDiffEntry de : event.diff.getDifferences()){
if(de.isAddition()){
DOTableModel.this.fireTableRowsInserted(de.getPosition(), de.getPosition());
}else{
DOTableModel.this.fireTableRowsDeleted(de.getPosition(), de.getPosition());
}
}
}
});
}
@Override
public int getRowCount() {
list.getRealm().exec(new Runnable(){
@Override
public void run() {
rowCount = list.size();
synchronized (lock) {
lock.notify();
}
}
});
synchronized (lock) {
while(rowCount == null){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return rowCount;
}
@Override
public int getColumnCount() {
return 11;
}
private void getObjectFromSWTRealm(final int rowIndex){
object = null;
list.getRealm().exec(new Runnable(){
@Override
public synchronized void run() {
object = (DOModel) list.get(rowIndex);
synchronized (lock) {
lock.notify();
}
}
});
synchronized (lock) {
while(object == null){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public Object getValueAt(final int rowIndex, int columnIndex) {
getObjectFromSWTRealm(rowIndex);
...
}
@Override
public void setValueAt(Object oValue, final int rowIndex, int columnIndex) {
getObjectFromSWTRealm(rowIndex);
...
}
@Override
public String getColumnName(int column) {
...
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
}
posted @
2012-04-05 23:46 West Farmer 閱讀(700) |
評論 (2) |
編輯 收藏
class Java {
Java Java;
Java() {
Java = Java(
this);
}
Java(Java Java) {
this.Java = Java;
}
Java Java() {
return Java.
this.Java;
}
Java Java(Java Java) {
return new Java(Java);
}
public static void main(String[] args) {
new Java().Java.Java().Java.Java();
}
}
原文地址
posted @
2012-04-05 23:25 West Farmer 閱讀(585) |
評論 (0) |
編輯 收藏
public static void main(String[] args) throws IOException {
File sourceFile = new File("c:\\java\\A.java");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
System.out.println(System.getProperties().getProperty("java.class.path") + ";F:\\IndigoSpace\\ejp");
compiler.run(null, null, null, "-cp", System.getProperties().getProperty("java.class.path") + ";F:\\IndigoSpace\\ejp", sourceFile.getPath());
System.out.println(new File("c:\\java\\").toURI().toURL());
URLClassLoader loader = new URLClassLoader(new URL[]{new File("c:\\java\\").toURI().toURL()});
try {
loader.loadClass("A");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
需要注意的是,上面的代碼只有在JDK上才能運行,因為JDK里面才有javac。而且在實際應用中,你還要
自己將package聲明轉換成文件目錄,否者裝載類的時候就會找不到。
posted @
2011-10-21 17:05 West Farmer 閱讀(332) |
評論 (0) |
編輯 收藏
摘要: 原文地址:http://stackoverflow.com/questions/15496/hidden-features-of-java我選擇幾個有趣的:1. Double Brace Initialization Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHi...
閱讀全文
posted @
2011-10-12 13:11 West Farmer 閱讀(370) |
評論 (2) |
編輯 收藏
Important:該類有諸多不盡人意的地方,讀者如果要用,請自行完善,但是至少值得一試。
原代碼是一個老外寫的在桌面右下角彈出消息提示的一個類,我進行了改寫。
任何改進,希望你能不吝分享。

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wb.swt.SWTResourceManager;
/**
* 具有淡入淡出效果且不需要用戶點擊關閉的消息提示框。
* @author ggfan@amarsoft
*
*/
public class Notifier {
private static final int DISPLAY_TIME = 2000;
private static final int FADE_TIMER = 50;
private static final int FADE_IN_STEP = 30;
private static final int FADE_OUT_STEP = 8;
private static final int FINAL_ALPHA = 225;
public static int DEFAULT_WIDTH = 150;
public static int DEFAULT_HEIGHT = 60;
private static Color _titleFgColor = SWTResourceManager.getColor(40, 73, 97);
private static Color _fgColor = _titleFgColor;
private static Color _bgFgGradient = SWTResourceManager.getColor(226, 239, 249);
private static Color _bgBgGradient = SWTResourceManager.getColor(177, 211, 243);
private static Color _borderColor = SWTResourceManager.getColor(40, 73, 97);
private static Image _oldImage;
// TODO Scrollable可能不合適
public static void notify(Scrollable scrollable, final String msg) {
final Shell parentShell = scrollable.getShell();
final Shell newShell = new Shell(parentShell, SWT.NO_FOCUS | SWT.NO_TRIM);
newShell.setLayout(new FillLayout());
newShell.setForeground(_fgColor);
newShell.setBackground(_bgBgGradient);
newShell.setBackgroundMode(SWT.INHERIT_FORCE);
scrollable.addDisposeListener(new DisposeListener(){ public void widgetDisposed(DisposeEvent e) {
newShell.dispose();
}
});
final Composite inner = new Composite(newShell, SWT.NONE);
FillLayout layout = new FillLayout();
layout.marginWidth = 20;
layout.marginHeight = 20;
inner.setLayout(layout);
newShell.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
try {
Rectangle rect = newShell.getClientArea();
Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height);
GC gc = new GC(newImage);
// 背景
gc.setForeground(_bgFgGradient);
gc.setBackground(_bgBgGradient);
gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);
// 邊框
gc.setLineWidth(2);
gc.setForeground(_borderColor);
gc.drawRectangle(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2);
gc.dispose();
newShell.setBackgroundImage(newImage);
if (_oldImage != null) {
_oldImage.dispose();
}
_oldImage = newImage;
} catch (Exception err) {
err.printStackTrace();
}
}
});
Label text = new Label(inner, SWT.WRAP | SWT.CENTER);
Font tf = text.getFont();
FontData tfd = tf.getFontData()[0];
tfd.setStyle(SWT.BOLD);
tfd.height = 8;
text.setFont(SWTResourceManager.getFont(tfd.getName(), 8, SWT.NORMAL));
text.setForeground(_fgColor);
text.setText(msg);
newShell.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
if (Display.getDefault().getActiveShell() == null || Display.getDefault().getActiveShell().getMonitor() == null) {
return;
}
newShell.setLocation(computePoint(scrollable));
newShell.setAlpha(0);
newShell.setVisible(true);
fadeIn(newShell);
}
// TODO 當有滾動條出現的時候是否能夠居中?
private static Point computePoint(Scrollable scrollable) {
Point p = scrollable.toDisplay(scrollable.getClientArea().x, scrollable.getClientArea().y);
int w = scrollable.getClientArea().width;
int h = scrollable.getClientArea().height;
p.x += w / 2 - DEFAULT_WIDTH / 2 ;
p.y += h / 2 - DEFAULT_HEIGHT / 2;
return p;
}
private static void fadeIn(final Shell _shell) {
Runnable run = new Runnable() {
@Override
public void run() {
try {
if (_shell == null || _shell.isDisposed()) {
return;
}
int cur = _shell.getAlpha();
cur += FADE_IN_STEP;
if (cur > FINAL_ALPHA) {
_shell.setAlpha(FINAL_ALPHA);
startTimer(_shell);
return;
}
_shell.setAlpha(cur);
Display.getDefault().timerExec(FADE_TIMER, this);
} catch (Exception err) {
err.printStackTrace();
}
}
};
Display.getDefault().timerExec(FADE_TIMER, run);
}
private static void startTimer(final Shell _shell) {
Runnable run = new Runnable() {
@Override
public void run() {
try {
if (_shell == null || _shell.isDisposed()) {
return;
}
fadeOut(_shell);
} catch (Exception err) {
err.printStackTrace();
}
}
};
Display.getDefault().timerExec(DISPLAY_TIME, run);
}
private static void fadeOut(final Shell _shell) {
final Runnable run = new Runnable() {
@Override
public void run() {
try {
if (_shell == null || _shell.isDisposed()) {
return;
}
int cur = _shell.getAlpha();
cur -= FADE_OUT_STEP;
if (cur <= 0) {
_shell.setAlpha(0);
if (_oldImage != null) {
_oldImage.dispose();
}
_shell.dispose();
return;
}
_shell.setAlpha(cur);
Display.getDefault().timerExec(FADE_TIMER, this);
} catch (Exception err) {
err.printStackTrace();
}
}
};
Display.getDefault().timerExec(FADE_TIMER, run);
}
}
posted @
2011-10-12 10:48 West Farmer 閱讀(3268) |
評論 (6) |
編輯 收藏

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.wb.swt.SWTResourceManager;
/**
* 關鍵字高亮編輯器。This class is a simple customized widget that wrappes a {@link org.eclipse.swt.custom.StyledText StyledText}.
* It consumes a keyword array and highlight them.
* @author ggfan@amarsoft
*
*/
public class KeywordsHighlightingEditor extends Composite{
private Color color = SWTResourceManager.getColor(SWT.COLOR_BLUE);
private Color variableColor = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
private String[] keywords;
private StyledText st;
public void setKeywordsColor(Color color){
this.color = color;
}
public void setKeywordsBgColor(Color color){
}
public IObservableValue observerContent(){
return SWTObservables.observeText(st, SWT.Modify);
}
public KeywordsHighlightingEditor(Composite parent, String[] keywords) {
super(parent, SWT.NONE);
this.keywords = keywords;
this.setLayout(new FillLayout());
st = new StyledText(this, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
// 禁止回車鍵換行
st.addVerifyKeyListener(new VerifyKeyListener(){
public void verifyKey(VerifyEvent event) {
if(event.keyCode == SWT.CR){
event.doit = false;
}
}
});
// Tab鍵失去焦點而不是插入制表符
st.addTraverseListener(new TraverseListener(){
public void keyTraversed(TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
e.doit = true;
}
}
});
st.addLineStyleListener(new SQLSegmentLineStyleListener());
}
private class SQLSegmentLineStyleListener implements LineStyleListener {
@Override
public void lineGetStyle(LineStyleEvent event) {
if(keywords == null || keywords.length == 0){
return;
}
List<StyleRange> styles = new ArrayList<StyleRange>();
int start = 0;
int length = event.lineText.length();
while (start < length) {
if (Character.isLetter(event.lineText.charAt(start))) {
StringBuffer buf = new StringBuffer();
int i = start;
for (; i < length && Character.isLetter(event.lineText.charAt(i)); i++) {
buf.append(event.lineText.charAt(i));
}
if(Arrays.asList(keywords).contains(buf.toString())) {
styles.add(new StyleRange(event.lineOffset + start, i - start, color, null, SWT.BOLD));
}
start = i;
}else if (event.lineText.charAt(start) == '#') {
StringBuffer buf = new StringBuffer();
buf.append('#');
int i = start + 1;
for (; i < length && Character.isLetter(event.lineText.charAt(i)); i++) {
buf.append(event.lineText.charAt(i));
}
if(buf.toString().matches("#[a-zA-Z]+\\d?")) {
styles.add(new StyleRange(event.lineOffset + start, i - start, variableColor, null, SWT.NORMAL));
}
start = i;
}
else{
start ++;
}
}
event.styles = (StyleRange[]) styles.toArray(new StyleRange[0]);
}
}
}
posted @
2011-10-12 10:42 West Farmer 閱讀(934) |
評論 (0) |
編輯 收藏
http://stackoverflow.com
這個是英文的,比起國內的的一些編程問答網站不知道要強多少倍。
國內的問答類網站,各種答非所問,各種閑聊,各種復制粘貼。
do not google it before you think about it deep enough
do not ask before you google it
posted @
2011-10-11 17:02 West Farmer 閱讀(191) |
評論 (0) |
編輯 收藏
有的時候應用程序會hold一個對象實例,隨著時間的推移,該對象所含的數據可能發生變化(比如調用setter方法改變一個屬性的值)。
那么如何明確相比于一個特定的時刻,某個對象實例中的數據發生了變化呢?
方法肯定不止一種,我的方法是:
public static String hashOf(Serializable object) throws IOException, NoSuchAlgorithmException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(baos);
oo.writeObject(object);
oo.flush();
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] data = baos.toByteArray();
oo.close();
baos.close();
messageDigest.update(data, 0, data.length);
BigInteger hash = new BigInteger(1, messageDigest.digest());
return String.format("%1$032X", hash);
}
說白了就是把一個對象實例看作byte數組,然后對這個byte數組計算MD5,如果MD5值一樣就表示所含數據一致。
MD5算法不是完美的,但是在實際應用中已經足夠的,你也可以使用CRC32。
歡迎指正。
posted @
2011-10-11 16:51 West Farmer 閱讀(315) |
評論 (0) |
編輯 收藏
摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->package amarsoft.rcp.base.widgets;import java.io.File;import java.io.FileInputStream;im...
閱讀全文
posted @
2011-10-11 16:28 West Farmer 閱讀(1543) |
評論 (2) |
編輯 收藏