久しぶりのブログだな。
今日は【お前の体重を見ろ!】をバージョンアップしようと思ってアイコンを作ってみた。
今回はiPhoneとAndroid両方対応するつもりで、
アンドロイドっぽくないアイコンを考えて、俺が唯一に作れるクマを選んでデブにしてみた。
バージョン1とキャラクターが違うけど、まぁ。。いい。
これが頑張って作った太ったクマ!
俺ちょっとデザインのうでが上がったんじゃない?
ちなみに2年前の俺はこんなデザインをしていた。
おお!発展してる。
2011年11月14日月曜日
2010年11月28日日曜日
갤럭시탭 에뮬레이터를 설치해보자.
갤럭시탭 에뮬레이터를 설치해보자.
참고 사이트는 「http://innovator.samsungmobile.com/galaxyTab.do」
Android SDK and AVD Manager를 열고,

Available Packages에
「http://innovator.samsungmobile.com/android/repository/srepository.xml」사이트를 추가.

추가후 「GALAXY Tab Addon」을 설치.



애뮬레이터 설치.


실행해보니.
제 컴퓨터에서는 한화면에 안보이는군요.
iPad 애뮬레이터처럼 50%로 축소해서 볼 수 있으면 좋을 듯 하지만 좀 아쉽군요.
참고 사이트는 「http://innovator.samsungmobile.com/galaxyTab.do」
Android SDK and AVD Manager를 열고,

Available Packages에
「http://innovator.samsungmobile.com/android/repository/srepository.xml」사이트를 추가.

추가후 「GALAXY Tab Addon」을 설치.



애뮬레이터 설치.


실행해보니.
제 컴퓨터에서는 한화면에 안보이는군요.
iPad 애뮬레이터처럼 50%로 축소해서 볼 수 있으면 좋을 듯 하지만 좀 아쉽군요.
2010年9月3日金曜日
[Android] 니 몸무게를 봐라! v1.0
「니 몸무게를 봐라!」v1.0를 릴리스하였다.
「니 몸무게를 봐라!」는 간단한 체중관리 무료 안드로이드 어플이다.
Support languages
- English
- 日本語
- 한국어
v1.0의 변경점은 (전 버젼 v9.0 링크)
1. 공유기능추가
- 메일 또는 트위터 클라이언트와 연동
(용감하게 자신의 몸무게 그래프를 공개가능 ^^;)
2. CSV가져오기 기능 추가.
3. 아이콘 변경
다음번에는 사용자들 요청도 있고해서 잠금기능을 추가할까 생각중이다.






「니 몸무게를 봐라!」는 간단한 체중관리 무료 안드로이드 어플이다.
Support languages
- English
- 日本語
- 한국어
v1.0의 변경점은 (전 버젼 v9.0 링크)
1. 공유기능추가
- 메일 또는 트위터 클라이언트와 연동
(용감하게 자신의 몸무게 그래프를 공개가능 ^^;)
2. CSV가져오기 기능 추가.
3. 아이콘 변경
다음번에는 사용자들 요청도 있고해서 잠금기능을 추가할까 생각중이다.






時刻:
金曜日, 9月 03, 2010
2010年9月1日水曜日
[Android] 로그 레벨 설정방법
Android 로그 레벨 설정방법
에뮬레이터와 단말기의 로그레벨이 아무래도 기본 「INFO」인듯하다.
테스트해보면
그렇기 때문에 아래와 같은 경우는 로그가 출력되지만,
다음의 코드는 출력되지 않는다.
특정 로그태그의 로그레벨을 설정하는 방법은
예를 들어 TAG가 「BABUKUMA」인 경우는
다시 테스트해본 결과는
에뮬레이터와 단말기의 로그레벨이 아무래도 기본 「INFO」인듯하다.
테스트해보면
Log.isLoggable(TAG, Log.VERBOSE) == false
Log.isLoggable(TAG, Log.DEBUG) == false
Log.isLoggable(TAG, Log.INFO) == true
Log.isLoggable(TAG, Log.WARN) == true
Log.isLoggable(TAG, Log.ERROR) == true
그렇기 때문에 아래와 같은 경우는 로그가 출력되지만,
Log.d(TAG, msg); // 로그레벨과 상관없이 출력됨.
다음의 코드는 출력되지 않는다.
if(Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, msg); // 로그레벨이 「DEBUG」이상인 경우, 출력됨.
}
특정 로그태그의 로그레벨을 설정하는 방법은
$ ./adb shell setprop log.tag.<your_log_tag> <level>
예를 들어 TAG가 「BABUKUMA」인 경우는
$ ./adb shell stop
$ ./adb shell setprop log.tag.BABUKUMA DEBUG
$ ./adb shell start
다시 테스트해본 결과는
Log.isLoggable(TAG, Log.VERBOSE) == false
Log.isLoggable(TAG, Log.DEBUG) == true
Log.isLoggable(TAG, Log.INFO) == true
Log.isLoggable(TAG, Log.WARN) == true
Log.isLoggable(TAG, Log.ERROR) == true
時刻:
水曜日, 9月 01, 2010
2010年8月30日月曜日
[iPhone] UIWebView의 링크를Safari로 열기
UIWebView의 링크를 Safari로 열기
참고링크:
결론은 UIWebViewDelegate를 이용한다.
Interface Builder에서 UIWebView의 delegate를 설정하고,

다음의 코드를 추가한다.
테스트시 사용한 전체 코드
WebViewTestAppDelegate.h
WebViewTestAppDelegate.m
참고링크:
- http://developer.apple.com/iphone/library/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIWebViewDelegate/webView:shouldStartLoadWithRequest:navigationType:
- http://developer.apple.com/iphone/library/documentation/uikit/reference/UIWebView_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UIWebView
- http://forums.macrumors.com/showthread.php?t=535312
결론은 UIWebViewDelegate를 이용한다.
Interface Builder에서 UIWebView의 delegate를 설정하고,

다음의 코드를 추가한다.
// 링크를 클릭했을 때, Safari를 열기위한 처리.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSLog(@"URL = %@", [[request URL] absoluteString]);
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
테스트시 사용한 전체 코드
WebViewTestAppDelegate.h
//
// WebViewTestAppDelegate.h
// WebViewTest
//
// Created by BABUKUMA on 10/08/30.
// Copyright babukuma.com 2010. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface WebViewTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
IBOutlet UIWebView *webView;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
WebViewTestAppDelegate.m
//
// WebViewTestAppDelegate.m
// WebViewTest
//
// Created by BABUKUMA on 10/08/30.
// Copyright babukuma.com 2010. All rights reserved.
//
#import "WebViewTestAppDelegate.h"
@implementation WebViewTestAppDelegate
@synthesize window;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[window makeKeyAndVisible];
// WebViewの初期表示
NSLog(@"BABUKUMA : WebViewの初期表示");
NSURL *url = [NSURL URLWithString:@"http://babukuma.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest: request];
return YES;
}
// リンクをクリック時、Safariを起動する為の処理
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSLog(@"URL = %@", [[request URL] absoluteString]);
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
}
- (void)dealloc {
[window release];
[super dealloc];
}
@end
時刻:
月曜日, 8月 30, 2010
2010年8月5日木曜日
[Android] 니 몸무게를 봐라! v0.9
오늘 「니 몸무게를 봐라!」v0.9를 업데이트하였다.
「니 몸무게를 봐라!」는 간단한 체중관리 무료 안드로이드 어플이다.
v0.9
1. 체지방그래프 추가
2. BMI와 BMR 용어설명 추가
3. 버그수정
- 체중그래프에 (kg)만 표시되는 버그






다음에는 CSV파일 가져오기를 추가해야겠다.
「니 몸무게를 봐라!」는 간단한 체중관리 무료 안드로이드 어플이다.
v0.9
1. 체지방그래프 추가
2. BMI와 BMR 용어설명 추가
3. 버그수정
- 체중그래프에 (kg)만 표시되는 버그






다음에는 CSV파일 가져오기를 추가해야겠다.
時刻:
木曜日, 8月 05, 2010
2010年7月7日水曜日
Scala WebApplication + Maven 프로젝트 구성
Scala WebApplication + Maven 프로젝트 구성
1. WebApplication프로젝트 작성
2. 디렉토리 구성
- java소스
・src/main/java
・src/test/java (테스트용)
- scala소스
・src/main/scala
・src/test/scala (테스트용)
- resources
・src/main/resources
・src/test/resources (테스트용)
- WebApplication파일
・src/main/webapp
・src/test/webapp (테스트용)

3. pom.xml
4. 테스트용 소스(Servlet)
HelloScalaServlet.scala
5. web.xml
6. 동작확인
1. WebApplication프로젝트 작성
mvn archetype:create -DgroupId=com.babukuma -DartifactId=Scala.Web -DarchetypeArtifactId=maven-archetype-webapp
2. 디렉토리 구성
- java소스
・src/main/java
・src/test/java (테스트용)
- scala소스
・src/main/scala
・src/test/scala (테스트용)
- resources
・src/main/resources
・src/test/resources (테스트용)
- WebApplication파일
・src/main/webapp
・src/test/webapp (테스트용)

3. pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.babukuma</groupId>
<artifactId>Scala.Web</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Scala.Web Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdkVersion>1.6</jdkVersion>
<junitVersion>4.8.1</junitVersion>
<scalaVersion>2.8.0.RC7</scalaVersion>
<scalaPluginVersion>2.12</scalaPluginVersion>
</properties>
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junitVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_2.5_spec</artifactId>
<version>1.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scalaVersion}</version>
</dependency>
</dependencies>
<build>
<finalName>Scala.Web</finalName>
<!-- To define the plugin version in your parent POM -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdkVersion}</source>
<target>${jdkVersion}</target>
</configuration>
</plugin>
<!-- To use the plugin goals in your POM or parent POM -->
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArgs>
<jvmArg>-Xms64m</jvmArg>
<jvmArg>-Xmx1024m</jvmArg>
</jvmArgs>
</configuration>
</plugin>
</plugins>
</build>
<!-- To use the report goals in your POM or parent POM -->
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</reporting>
</project>
4. 테스트용 소스(Servlet)
HelloScalaServlet.scala
package com.babukuma
import javax.servlet.http._
class HelloScalaServlet extends HttpServlet {
override def doGet(request : HttpServletRequest, response : HttpServletResponse) =
response.getWriter().print("Hello Scala")
}
5. web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Scala Web Application</display-name>
<servlet>
<servlet-name>helloScala</servlet-name>
<servlet-class>com.babukuma.HelloScalaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloScala</servlet-name>
<url-pattern>/helloScala</url-pattern>
</servlet-mapping>
</web-app>
6. 동작확인
時刻:
水曜日, 7月 07, 2010
2010年7月6日火曜日
Scala + Maven2 프로젝트 구성
참조URL
- http://scala-tools.org/mvnsites/maven-scala-plugin/
- http://www.scala-lang.org/node/345
pom.xml파일
디렉토리 구성
- java소스
・src/main/java
・src/test/java (테스트용)
- scala소스
・src/main/scala
・src/test/scala (테스트용)
- resources
・src/main/resources
・src/test/resources (테스트용)

테스트 소스
HelloScala.scala
HelloJava.java
컴파일과 패키징
- http://scala-tools.org/mvnsites/maven-scala-plugin/
- http://www.scala-lang.org/node/345
pom.xml파일
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.babukuma</groupId>
<artifactId>scala.test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>scala.test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junitVersion>4.8.1</junitVersion>
<scalaVersion>2.8.0.RC7</scalaVersion>
<scalaPluginVersion>2.12</scalaPluginVersion>
</properties>
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junitVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scalaVersion}</version>
</dependency>
</dependencies>
<build>
<!--
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
-->
<!-- To define the plugin version in your parent POM -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- To use the plugin goals in your POM or parent POM -->
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArgs>
<jvmArg>-Xms64m</jvmArg>
<jvmArg>-Xmx1024m</jvmArg>
</jvmArgs>
</configuration>
</plugin>
</plugins>
</build>
<!-- To use the report goals in your POM or parent POM -->
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>${scalaPluginVersion}</version>
</plugin>
</plugins>
</reporting>
</project>
디렉토리 구성
- java소스
・src/main/java
・src/test/java (테스트용)
- scala소스
・src/main/scala
・src/test/scala (테스트용)
- resources
・src/main/resources
・src/test/resources (테스트용)

테스트 소스
HelloScala.scala
package com.babukuma.scala
object HelloScala {
def main(args: Array[String]): Unit = {
println("Hello Scala!")
val helloJava = new HelloJava
helloJava.printHelloJava()
}
}
HelloJava.java
package com.babukuma.scala;
public class HelloJava {
public void printHelloJava() {
System.out.println("Hello Java!");
}
}
컴파일과 패키징
$ mvn compile
$ mvn package
실행
$ mvn scala:run -DmainClass=com.babukuma.scala.HelloScala
Hello Scala!
Hello Java!
時刻:
火曜日, 7月 06, 2010
2010年4月9日金曜日
SQLite과 H2의 성능비교
궁금해서 임베디드 DB인 H2와 SQLite3를 비교해보았다.
SQLite 버젼 : 3.6.23
H2 버젼 : 1.2.132
둘다 사용할 프로젝트가 Java인 관계로 언어는 Java로.
SQLite는 JDBC드라이버인 SQLiteJDBC를 사용하였다.
SQLiteJDBC : http://www.zentus.com/sqlitejdbc/
- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
비록 간단한 테스트이지만 대략적으로 SQLite가 우세한 듯 보인다.
특히 성능이 낮은 머신에서 H2와의 성능차이가 뚜렷하다.
그리고 H2는 여지껏 「In-memory」방식이 「임베디드」방식보다 성능이 더 좋을 줄 알았는데,
전혀 생각과 틀려 충격이었다.
테스트용 소스는 아래와 같다.
SQLite 버젼 : 3.6.23
H2 버젼 : 1.2.132
둘다 사용할 프로젝트가 Java인 관계로 언어는 Java로.
SQLite는 JDBC드라이버인 SQLiteJDBC를 사용하였다.
SQLiteJDBC : http://www.zentus.com/sqlitejdbc/
테스트 환경 1
- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
| 구분 | SQLite | H2 Embedded | H2 In-memory |
|---|---|---|---|
| Insert (100만건) | 0.5 초 | 0.9 초 | 0.9 초 |
| Select (100만건) | 0.002 초 | 0.015 초 | 0.07 초 |
| File size | 2,048 bytes | 14,336 bytes | - |
테스트 환경 2
- CPU : 2.53 GHz Intel Core 2 Duo
- Memory : 4GB
- OS : Mac OS X 10.6.3
| 구분 | SQLite | H2 Embedded | H2 In-memory |
|---|---|---|---|
| Insert (100만건) | 0.5 초 | 1.3 초 | 1.5 초 |
| Select (100만건) | 0.004 초 | 0.09 초 | 0.095 초 |
| File size | 2,048 bytes | 14,336 bytes | - |
비록 간단한 테스트이지만 대략적으로 SQLite가 우세한 듯 보인다.
특히 성능이 낮은 머신에서 H2와의 성능차이가 뚜렷하다.
그리고 H2는 여지껏 「In-memory」방식이 「임베디드」방식보다 성능이 더 좋을 줄 알았는데,
전혀 생각과 틀려 충격이었다.
테스트용 소스는 아래와 같다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class SqlitePerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;
/**
* SQLite3 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("SQLite TEST [" + ROW_COUNT + "件]");
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager
.getConnection("jdbc:sqlite:babukuma.sqllite.db");
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id integer primary key, value integer);");
conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();
PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");
for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();
if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}
conn.commit();
long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");
System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");
conn.close();
}
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import org.h2.jdbcx.JdbcConnectionPool;
public class H2Performance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;
/**
* H2 Embedded
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool.create(
"jdbc:h2:babukuma.h2", "", "");
Connection conn = cp.getConnection();
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");
conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();
PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");
for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();
if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}
conn.commit();
long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");
System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");
conn.close();
}
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import org.h2.jdbcx.JdbcConnectionPool;
public class H2InMemoryPerformance {
private static final int ROW_COUNT = 1000000;
private static final int MAX = 100;
/**
* H2 In memory
*
* @author babukuma
* @since 2010/04/09
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("H2 In Memory TEST [" + ROW_COUNT + "件]");
JdbcConnectionPool cp = JdbcConnectionPool
.create("jdbc:h2:mem:", "", "");
Connection conn = cp.getConnection();
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists babukuma;");
stat
.executeUpdate("create table babukuma (id int primary key, value int);");
conn.setAutoCommit(false);
System.out.print("Insert Test : ");
long startTime = System.currentTimeMillis();
PreparedStatement prep = conn
.prepareStatement("insert into babukuma values (?, ?);");
for (int i = 0; i < ROW_COUNT; i++) {
prep.setInt(1, i);
prep.setInt(2, i);
prep.addBatch();
if (i > 0 && (i % MAX) == 0 && i == ROW_COUNT - 1) {
prep.executeBatch();
prep.clearBatch();
}
}
conn.commit();
long endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");
System.out.print("Select Test : ");
startTime = System.currentTimeMillis();
ResultSet rs = stat.executeQuery("select * from babukuma;");
while (rs.next()) {
rs.getInt("id");
rs.getInt("value");
// System.out.println("id = " + rs.getInt("id"));
// System.out.println("value = " + rs.getString("value"));
}
rs.close();
endTime = System.currentTimeMillis();
System.out.println(((endTime - startTime) / 1000.) + "秒");
conn.close();
}
}
時刻:
金曜日, 4月 09, 2010
2010年3月15日月曜日
[SWT] SWT on 64bit Mac OS X
Mac OS X 10.6.2 Snow Leopard위에
SWT어플리케이션을 실행시키면 뭔가 제대로 실행이 안되는 현상이 있다.
그래서 이것저것 찾아보니 몇가지 옵션이 필요한 듯 하다.
「-d64」옵션과 「-XstartOnFirstThread」옵션
「-d64」옵션 : 명확하게 64bit VM에서 동작하도록 지정해준다.
「-XstartOnFirstThread」옵션 : Mac에서 SWT어플리케이션이 정상적으로 동작하는데 필요한 옵션인 듯 하다. SWT에 한정된 옵션은 아닌 듯.
두 옵션을 실제 사용해 보면
java -d64 -XstartOnFirstThread -jar babukuma_swt_test.jar
실제 테스트에서 문제없이 작동하였다.
참고한 사이트.
http://www.eclipse.org/swt/macosx
http://www.eclipse.org/swt/faq.php
SWT어플리케이션을 실행시키면 뭔가 제대로 실행이 안되는 현상이 있다.
그래서 이것저것 찾아보니 몇가지 옵션이 필요한 듯 하다.
「-d64」옵션과 「-XstartOnFirstThread」옵션
「-d64」옵션 : 명확하게 64bit VM에서 동작하도록 지정해준다.
「-XstartOnFirstThread」옵션 : Mac에서 SWT어플리케이션이 정상적으로 동작하는데 필요한 옵션인 듯 하다. SWT에 한정된 옵션은 아닌 듯.
두 옵션을 실제 사용해 보면
java -d64 -XstartOnFirstThread -jar babukuma_swt_test.jar
실제 테스트에서 문제없이 작동하였다.
참고한 사이트.
http://www.eclipse.org/swt/macosx
http://www.eclipse.org/swt/faq.php
時刻:
月曜日, 3月 15, 2010
2010年3月10日水曜日
[Android] Android NDK r3를 사용해보다.
이번에 새로 릴리즈된 Android NDK r3를 사용해보았다.
OS는 Mac OS X 10.6.2
android-ndk-r3-darwin-x86.zip파일을 「http://developer.android.com/」사이트에서 다운로드하고 적당한 곳에 압축을 풀어놨다.
나는 「/Users/babukuma/dev/android-ndk-r3」이 경로에 풀어놨다.(이하 $NDK)
1. Android프로젝트 생성.
테스트용으로 프로젝트를 생성.

생성되면 프로젝트는 아마도 이런 구조.

여기서 「jni」폴더를 생성.

2. 「Application.mk」파일을 작성.
프로젝트 밑에 「Application.mk」파일을 작성한다.

여기서는 모듈명을 「jnitest」로 하였다.
작성법은 「$NDK/docs/APPLICATION-MK.TXT」파일을 참조.
3. Native메소드를 작성
「Main.java」파일에 작성하였다.
4. 헤더파일 생성.
프로젝트 디렉토리에서 「javah」를 커맨드로 헤더파일「jni/jnitest.h」을 생성.

생성된 「jnitest.h」파일
5. C소스 작성
「jni」디렉토리에 「jnitest.c」파일을 작성한다.

작성한 「jnitest.c」파일
6. 「Android.mk」파일을 작성.
「jni」디렉토리에 「Android.mk」파일을 작성한다.
작성법은 「$NDK/docs/ANDROID-MK.TXT」을 참조.

작성한「Android.mk」파일
7. C소스 빌드
빌드를 하기위해서는 프로젝트의 PATH가 「$NDK/apps/<프로젝트명>」여야할 필요가 있으므로 링크를 작성하였다.

$NDK디렉토리에서 「make APP=jnitest」로 빌드.
여기서 「jnitest」는 「$NDK/apps/」밑의 프로젝트폴더명이 된다.

Eclipse를 새로고침하면 「libs/armeabi/libjnitest.so」파일이 생성되어있는 것을 알 수 있다.

8. Java소스를 수정하여 실행해봄.
수정후의 「Main.java」파일
수정후 실행해보면 Native메소드가 문제없이 호출된 것을 알 수 있다.
OS는 Mac OS X 10.6.2
android-ndk-r3-darwin-x86.zip파일을 「http://developer.android.com/」사이트에서 다운로드하고 적당한 곳에 압축을 풀어놨다.
나는 「/Users/babukuma/dev/android-ndk-r3」이 경로에 풀어놨다.(이하 $NDK)
1. Android프로젝트 생성.
테스트용으로 프로젝트를 생성.

생성되면 프로젝트는 아마도 이런 구조.

여기서 「jni」폴더를 생성.

2. 「Application.mk」파일을 작성.
프로젝트 밑에 「Application.mk」파일을 작성한다.

여기서는 모듈명을 「jnitest」로 하였다.
작성법은 「$NDK/docs/APPLICATION-MK.TXT」파일을 참조.
# Application.mk
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := jnitest
3. Native메소드를 작성
「Main.java」파일에 작성하였다.
package com.babukuma.android.test.jni;
import android.app.Activity;
import android.os.Bundle;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public native String helloJNI();
public native int add(int a, int b);
}
4. 헤더파일 생성.
프로젝트 디렉토리에서 「javah」를 커맨드로 헤더파일「jni/jnitest.h」을 생성.

생성된 「jnitest.h」파일
/* DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/* Header for class com_babukuma_android_test_jni_Main */
#ifndef _Included_com_babukuma_android_test_jni_Main
#define _Included_com_babukuma_android_test_jni_Main
#ifdef __cplusplus
extern"C" {
#endif
/*
* Class: com_babukuma_android_test_jni_Main
* Method: helloJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_babukuma_android_test_jni_Main_helloJNI
(JNIEnv *, jobject);
/*
* Class: com_babukuma_android_test_jni_Main
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_babukuma_android_test_jni_Main_add
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
5. C소스 작성
「jni」디렉토리에 「jnitest.c」파일을 작성한다.

작성한 「jnitest.c」파일
#include<jni.h>
#include"jnitest.h"
JNIEXPORT jstring JNICALL Java_com_babukuma_android_test_jni_Main_helloJNI(
JNIEnv *env, jobject thisObj) {
jstring result = (*env)->NewStringUTF(env, "Hello JNI !");
return result;
}
JNIEXPORT jint JNICALL Java_com_babukuma_android_test_jni_Main_add(JNIEnv *env,
jobject thisObj, jint a, jint b) {
jint result = a + b;
return result;
}
6. 「Android.mk」파일을 작성.
「jni」디렉토리에 「Android.mk」파일을 작성한다.
작성법은 「$NDK/docs/ANDROID-MK.TXT」을 참조.

작성한「Android.mk」파일
# Android.mkLOCAL_PATH := $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE := jnitest
LOCAL_SRC_FILES := jnitest.c
include$(BUILD_SHARED_LIBRARY)
7. C소스 빌드
빌드를 하기위해서는 프로젝트의 PATH가 「$NDK/apps/<프로젝트명>」여야할 필요가 있으므로 링크를 작성하였다.

$NDK디렉토리에서 「make APP=jnitest」로 빌드.
여기서 「jnitest」는 「$NDK/apps/」밑의 프로젝트폴더명이 된다.

Eclipse를 새로고침하면 「libs/armeabi/libjnitest.so」파일이 생성되어있는 것을 알 수 있다.

8. Java소스를 수정하여 실행해봄.
수정후의 「Main.java」파일
package com.babukuma.android.test.jni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Main extends Activity {
static {
System.loadLibrary("jnitest");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// call helloJNI()
TextView result1 = (TextView) findViewById(R.id.text_result_1);
result1.setText(helloJNI());
// call add(1, 2)
TextView result2 = (TextView) findViewById(R.id.text_result_2);
result2.setText("1 + 2 = " + add(1, 2));
}
public native String helloJNI();
public native int add(int a, int b);
}
수정후 실행해보면 Native메소드가 문제없이 호출된 것을 알 수 있다.
時刻:
水曜日, 3月 10, 2010
2010年2月22日月曜日
[Android] 가속도센서를 사용해보다.
Android 가속센서를 사용해보다.
가속도센서를 등록하면 SensorEvent의 values배열에 x, y, z의 가속도가 순서대로 들어오기 때문에 의외로 간단하게 사용할 수 있었다.
가속도센서에 따라 이미지가 움직인다.


Activity를 등록할 때 화면을 수직으로 고정시켰다.(수직방향이 계산하기 쉬워서)
확인하기 편하도록 화면에는 간단한 이미지를 출력하고 가속도에 따라 위치를 변경시키도록 하였다.
가속도센서를 등록하면 SensorEvent의 values배열에 x, y, z의 가속도가 순서대로 들어오기 때문에 의외로 간단하게 사용할 수 있었다.
가속도센서에 따라 이미지가 움직인다.


Activity를 등록할 때 화면을 수직으로 고정시켰다.(수직방향이 계산하기 쉬워서)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.babukuma.android.test" android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".SensorActivity" android:screenOrientation="portrait"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
</manifest>
확인하기 편하도록 화면에는 간단한 이미지를 출력하고 가속도에 따라 위치를 변경시키도록 하였다.
package com.babukuma.android.test;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class SensorActivity extends Activity implements SensorEventListener {
private static final String LOG_TAG = "BABUKUMA";
private SensorManager sensorManager;
private SensorView sensorView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensorView = new SensorView(this);
setContentView(sensorView);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// 加速度センサー
List<Sensor> sensors = sensorManager
.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (sensors.size() > 0) {
sensorManager.registerListener(this, sensors.get(0),
SensorManager.SENSOR_DELAY_GAME);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
sensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(final Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(final SensorEvent event) {
Sensor sensor = event.sensor;
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
// Log.d(LOG_TAG, "ACCELEROMETER : " + event.values[0] + ","
// + event.values[1] + "," + event.values[2]);
sensorView.move(event.values[0], event.values[1]);
break;
default:
break;
}
}
class SensorView extends View {
private static final int KUMA_SIZE = 50;
private Bitmap kuma;
private int w;
private int h;
private float x;
private float y;
public SensorView(Context context) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
kuma = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_kuma_50);
}
/**
* クマを移動する。
*
* @param mx
* @param my
*/
public void move(float mx, float my) {
this.x -= (mx * 4f);
this.y += (my * 4f);
if (this.x < 0) {
this.x = 0;
} else if ((this.x + KUMA_SIZE) > this.w) {
this.x = this.w - KUMA_SIZE;
}
if (this.y < 0) {
this.y = 0;
} else if ((this.y + KUMA_SIZE) > this.h) {
this.y = this.h - KUMA_SIZE;
}
invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
this.w = w;
this.h = h;
this.x = (w - KUMA_SIZE) / 2f;
this.y = (h - KUMA_SIZE) / 2f;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(kuma, x, y, null);
}
}
}
時刻:
月曜日, 2月 22, 2010
2010年2月5日金曜日
Mac OS X에 MySQL 설치
환경
OS : Mac OS X 10.6.2
MySQL : 5.1.43
1. MySQL 다운로드
- http://dev.mysql.com/downloads/mysql/ 에서 다운로드
- mysql-5.1.43-osx10.6-x86_64.dmg
2. 인스톨
- 다운로드한 파일을 실행

- 「mysql-XXXXXX.pkg」(여기서는 「mysql-5.1.43-osx10.6-x86_64.pkg」)을 실행
- MySQL.prefPane을 설치(더블클릭으로.)


3. MySQL서버 시작과 정지
- 콘솔창에서 커맨드로도 가능하지만 시스템환경설정화면에서 간단하게 조작가능.


4. MySQL언인스톨
- MySQL.prefPane제거

- mysql이 설치된 디렉토리를 삭제
디폴트면 「/usr/local/mysql-5.1.43-osx10.6-x86_64」와 「/usr/local/mysql」를 삭제하면 된다.
OS : Mac OS X 10.6.2
MySQL : 5.1.43
1. MySQL 다운로드
- http://dev.mysql.com/downloads/mysql/ 에서 다운로드
- mysql-5.1.43-osx10.6-x86_64.dmg
2. 인스톨
- 다운로드한 파일을 실행

- 「mysql-XXXXXX.pkg」(여기서는 「mysql-5.1.43-osx10.6-x86_64.pkg」)을 실행
- MySQL.prefPane을 설치(더블클릭으로.)


3. MySQL서버 시작과 정지
- 콘솔창에서 커맨드로도 가능하지만 시스템환경설정화면에서 간단하게 조작가능.


4. MySQL언인스톨
- MySQL.prefPane제거

- mysql이 설치된 디렉토리를 삭제
디폴트면 「/usr/local/mysql-5.1.43-osx10.6-x86_64」와 「/usr/local/mysql」를 삭제하면 된다.
時刻:
金曜日, 2月 05, 2010
2010年2月1日月曜日
[Django] Django를 Tomcat에서 실행하기.
Jython을 사용하여 Django프레임워크를 Tomcat에서 실행하여 보았다.
1. Jython을 설치
- http://jython.org 에서 다운로드
- 2.5.1버젼을 인스톨하였다.
- 환경변수에 「JYTHON_HOME」작성
- [Jython] MACでjythonをインストールしてみた。를 참고.
2. Django를 설치
- http://www.djangoproject.com
- Django-1.1.1.tar.gz을 다운로드하였다.
- # sudo jython setup.py install 로 설치
3. django-jython을 설치
- http://code.google.com/p/django-jython
- # sudo jython setup.py install
4. Django용 프로젝트를 작성(여기서는 django_test로)
- # jython $JYTHON_HOME/bin/django-admin.py startproject django_test
5. 「settings.py」파일 수정
6. Hello Django페이지를 작성
- hello_view.py
7. 「urls.py」파일을 수정
8. 테스트용 서버에서 확인
- # jython manager.py runserver

9. war파일 작성
- # jython manager.py war
- 「django_test.war」파일이 작성된다.
10. Tomcat에서 테스트

Tomcat위에서도 Django가 문제없이 돌아가는 것 같다.
1. Jython을 설치
- http://jython.org 에서 다운로드
- 2.5.1버젼을 인스톨하였다.
- 환경변수에 「JYTHON_HOME」작성
- [Jython] MACでjythonをインストールしてみた。를 참고.
2. Django를 설치
- http://www.djangoproject.com
- Django-1.1.1.tar.gz을 다운로드하였다.
- # sudo jython setup.py install 로 설치
3. django-jython을 설치
- http://code.google.com/p/django-jython
- # sudo jython setup.py install
4. Django용 프로젝트를 작성(여기서는 django_test로)
- # jython $JYTHON_HOME/bin/django-admin.py startproject django_test
5. 「settings.py」파일 수정
INSTALLED_APPS = ( 'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'doj', # 이부분을 추가함.
)
6. Hello Django페이지를 작성
- hello_view.py
'''
Created on 2010/02/01
@author: babukuma
'''
from django.http import HttpResponse
def hello(request):
"""Hello Django"""
message = "<html><body>Hello, Django on Jython!</body></html>"
return HttpResponse(message)
7. 「urls.py」파일을 수정
from django.conf.urls.defaults import *
from hello_view import * # 추가부분
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^django_test/', include('django_test.foo.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'hello/$', hello), # 추가부분
# Uncomment the next line to enable the admin:
# (r'^admin/', include(admin.site.urls)),
)
8. 테스트용 서버에서 확인
- # jython manager.py runserver

9. war파일 작성
- # jython manager.py war
- 「django_test.war」파일이 작성된다.
10. Tomcat에서 테스트

Tomcat위에서도 Django가 문제없이 돌아가는 것 같다.
時刻:
月曜日, 2月 01, 2010
2010年1月29日金曜日
[Android] Custom Component - DateTimePicker

DatePicker와 TimePicker를 이용하여 간단하게 만들어본 DateTimePicker
DatePicker와 TimePicker는 존재하지만, 왜인지 날짜와 시간을 한번에 설정할 수 있는 컨포넌트가 안보인다.
그래서 간단하게 만들어봤다.
우선 레이아웃 구성 [res/layout/datetime_picker.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:gravity="center">
<DatePicker android:id="@+id/_babukuma_datetime_picker_date_picker"
android:layout_width="wrap_content" android:layout_height="wrap_content"></DatePicker>
<CheckBox android:id="@+id/_babukuma_datetime_picker_enable_time"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="enable Time"></CheckBox>
<TimePicker android:id="@+id/_babukuma_datetime_picker_time_picker"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TimePicker>
</LinearLayout>
다음은 몇가지 필요할 것 같은 Attribute를 정의 [res/values/attrs.xml]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DataTimePicker">
<attr name="enableTime" format="boolean" />
<attr name="year" format="integer" />
<attr name="month" format="integer" />
<attr name="day" format="integer" />
<attr name="hour" format="integer" />
<attr name="minute" format="integer" />
</declare-styleable>
</resources>
다음으로는 DateTimePicker의 소스다. [DateTimePicker.java]
대부분이 기존의 DatePicker와 TimePicker가 가지고 있는 메소드를 그대로 사용하도록 했고,
단지 하단의 TimePicker를 CheckBox를 이용해서 활성화/비활성화 시킨 것 뿐이다.
/**
* http://babukuma.com
*/
package com.babukuma.android.view;
import java.util.Calendar;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.TimePicker;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.TimePicker.OnTimeChangedListener;
import com.babukuma.android.test.R;
/**
* @author babukuma
*/
public class DateTimePicker extends LinearLayout {
/**
* @author babukuma
*/
public interface OnDateTimeChangedListener {
/**
* @param view
* The view associated with this listener.
* @param year
* The year that was set.
* @param monthOfYear
* The month that was set (0-11) for compatibility with
* {@link java.util.Calendar}.
* @param dayOfMonth
* The day of the month that was set.
* @param hourOfDay
* The current hour.
* @param minute
* The current minute.
*/
void onDateTimeChanged(DateTimePicker view, int year, int monthOfYear,
int dayOfMonth, int hourOfDay, int minute);
}
private OnDateTimeChangedListener onDateTimeChangedListener;
private final DatePicker datePicker;
private final CheckBox enableTimeCheckBox;
private final TimePicker timePicker;
/**
* @param context
*/
public DateTimePicker(final Context context) {
this(context, null);
}
/**
* @param context
* @param attrs
*/
public DateTimePicker(final Context context, final AttributeSet attrs) {
super(context, attrs);
// Layout
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.datetime_picker, this, true);
// Attribute
Calendar calendar = Calendar.getInstance();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.DataTimePicker);
final int _currentYear = a.getInt(R.styleable.DataTimePicker_year,
calendar.get(Calendar.YEAR));
final int _currentMonth = a.getInt(R.styleable.DataTimePicker_month,
calendar.get(Calendar.MONTH));
final int _currentDay = a.getInt(R.styleable.DataTimePicker_day,
calendar.get(Calendar.DAY_OF_MONTH));
final int _currentHour = a.getInt(R.styleable.DataTimePicker_hour,
calendar.get(Calendar.HOUR_OF_DAY));
final int _currentMinute = a.getInt(R.styleable.DataTimePicker_minute,
calendar.get(Calendar.MINUTE));
// DatePicker
datePicker = (DatePicker) findViewById(R.id._babukuma_datetime_picker_date_picker);
datePicker.init(_currentYear, _currentMonth, _currentDay,
new OnDateChangedListener() {
@Override
public void onDateChanged(final DatePicker view,
final int year, final int monthOfYear,
final int dayOfMonth) {
if (onDateTimeChangedListener != null) {
onDateTimeChangedListener.onDateTimeChanged(
DateTimePicker.this, year, monthOfYear,
dayOfMonth, timePicker.getCurrentHour(),
timePicker.getCurrentMinute());
}
}
});
// Enable Time checkbox
enableTimeCheckBox = (CheckBox) findViewById(R.id._babukuma_datetime_picker_enable_time);
enableTimeCheckBox
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
timePicker.setEnabled(isChecked);
timePicker.setVisibility((enableTimeCheckBox
.isChecked() ? View.VISIBLE : View.INVISIBLE));
}
});
// TimePicker
timePicker = (TimePicker) findViewById(R.id._babukuma_datetime_picker_time_picker);
timePicker.setOnTimeChangedListener(new OnTimeChangedListener() {
@Override
public void onTimeChanged(final TimePicker view,
final int hourOfDay, final int minute) {
if (onDateTimeChangedListener != null) {
onDateTimeChangedListener.onDateTimeChanged(
DateTimePicker.this, datePicker.getYear(),
datePicker.getMonth(), datePicker.getDayOfMonth(),
hourOfDay, minute);
}
}
});
timePicker.setCurrentHour(_currentHour);
timePicker.setCurrentMinute(_currentMinute);
timePicker.setEnabled(enableTimeCheckBox.isChecked());
timePicker.setVisibility((enableTimeCheckBox.isChecked() ? View.VISIBLE
: View.INVISIBLE));
}
public void setOnDateTimeChangedListener(
OnDateTimeChangedListener onDateTimeChangedListener) {
this.onDateTimeChangedListener = onDateTimeChangedListener;
}
public void updateDateTime(int year, int monthOfYear, int dayOfMonth,
int currentHour, int currentMinute) {
datePicker.updateDate(year, monthOfYear, dayOfMonth);
timePicker.setCurrentHour(currentHour);
timePicker.setCurrentMinute(currentMinute);
}
public void updateDate(int year, int monthOfYear, int dayOfMonth) {
datePicker.updateDate(year, monthOfYear, dayOfMonth);
}
public void setIs24HourView(final boolean is24HourView) {
timePicker.setIs24HourView(is24HourView);
}
public int getYear() {
return datePicker.getYear();
}
public int getMonth() {
return datePicker.getMonth();
}
public int getDayOfMonth() {
return datePicker.getDayOfMonth();
}
public int getCurrentHour() {
return timePicker.getCurrentHour();
}
public int getCurrentMinute() {
return timePicker.getCurrentMinute();
}
public boolean enableTime() {
return enableTimeCheckBox.isChecked();
}
}
나중에 좀더 속성을 추가하고, 살을 더 붙이면 쓸만할 것 같긴한데,
우선은 이것으로 대충 완성. 일단은 쓸 수는 있어보이니까.
다음은 간단하게 테스트.


테스트용 레이아웃 [res/layout/datetime_picker_test.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/datetime_picker_activity_text_view"
android:layout_width="fill_parent" android:layout_height="48dip"
android:textColor="#000000" android:background="#CCCCCC"
android:gravity="center" android:text="time"></TextView>
<com.babukuma.android.view.DateTimePicker
android:layout_width="wrap_content" android:layout_height="wrap_content"
year="2010" month="1" day="29" hour="14" minute="1" startYear="2000"
android:id="@+id/datetime_picker_activity_datetime_picker">
</com.babukuma.android.view.DateTimePicker>
</LinearLayout>
그리고 테스트용 소스 [DateTimePickerActivity.java]
package com.babukuma.android.test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.babukuma.android.view.DateTimePicker;
import com.babukuma.android.view.DateTimePicker.OnDateTimeChangedListener;
public class DateTimePickerActivity extends Activity {
final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datetime_picker_test);
final TextView timeView = (TextView) findViewById(R.id.datetime_picker_activity_text_view);
final DateTimePicker dateTimePicker = (DateTimePicker) findViewById(R.id.datetime_picker_activity_datetime_picker);
dateTimePicker
.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
@Override
public void onDateTimeChanged(DateTimePicker view,
int year, int monthOfYear, int dayOfMonth,
int hourOfDay, int minute) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, monthOfYear, dayOfMonth, hourOfDay,
minute);
timeView.setText(dateFormat.format(calendar.getTime()));
}
});
Calendar calendar = Calendar.getInstance();
calendar.set(dateTimePicker.getYear(), dateTimePicker.getMonth(),
dateTimePicker.getDayOfMonth(),
dateTimePicker.getCurrentHour(), dateTimePicker
.getCurrentMinute());
timeView.setText(dateFormat.format(calendar.getTime()));
}
}
다음에는 DateTimePickerDialog를 만들어봐야겠다.
時刻:
金曜日, 1月 29, 2010
登録:
投稿 (Atom)

