ベータ版移行版。作業部屋IDの綴り修正
Revision | 16ea37c4771fbba1b1dc1a1b3f3b8a8e60092083 (tree) |
---|---|
Time | 2015-08-07 14:07:22 |
Author | MirrgieRiana |
Commiter | MirrgieRiana |
projects: Gradleプロジェクトに移行
@@ -12,3 +12,5 @@ | ||
12 | 12 | workspace/.recommenders/ |
13 | 13 | workspace/ChlorophyllUploader/chlorophylluploader-setting.xml |
14 | 14 | workspace/ChlorophyllUploader/chlorophylluploader-setting.xml.orig |
15 | +workspace/*/.gradle/ | |
16 | +workspace/*/build/ |
@@ -1,31 +1,10 @@ | ||
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <classpath> |
3 | - <classpathentry kind="src" output="target/classes" path="src/main/java"> | |
4 | - <attributes> | |
5 | - <attribute name="optional" value="true"/> | |
6 | - <attribute name="maven.pomderived" value="true"/> | |
7 | - </attributes> | |
8 | - </classpathentry> | |
9 | - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |
10 | - <attributes> | |
11 | - <attribute name="optional" value="true"/> | |
12 | - <attribute name="maven.pomderived" value="true"/> | |
13 | - </attributes> | |
14 | - </classpathentry> | |
15 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |
16 | - <attributes> | |
17 | - <attribute name="maven.pomderived" value="true"/> | |
18 | - </attributes> | |
19 | - </classpathentry> | |
20 | - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |
21 | - <attributes> | |
22 | - <attribute name="maven.pomderived" value="true"/> | |
23 | - </attributes> | |
24 | - </classpathentry> | |
25 | - <classpathentry combineaccessrules="false" kind="src" path="/jp.hishidama"/> | |
26 | - <classpathentry combineaccessrules="false" kind="src" path="/mirrg.swing.helium"/> | |
27 | - <classpathentry kind="lib" path="mirrg.struct.hydrogen-20150715.jar"/> | |
28 | - <classpathentry combineaccessrules="false" kind="src" path="/mirrg.serial.fluorine"/> | |
29 | - <classpathentry combineaccessrules="false" kind="src" path="/TunnelSerialToIEEE1888"/> | |
30 | - <classpathentry kind="output" path="target/classes"/> | |
3 | + <classpathentry kind="src" path="src/main/java"/> | |
4 | + <classpathentry kind="src" path="src/main/resources"/> | |
5 | + <classpathentry kind="src" path="src/test/java"/> | |
6 | + <classpathentry kind="src" path="src/test/resources"/> | |
7 | + <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |
8 | + <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/> | |
9 | + <classpathentry kind="output" path="bin"/> | |
31 | 10 | </classpath> |
@@ -10,14 +10,9 @@ | ||
10 | 10 | <arguments> |
11 | 11 | </arguments> |
12 | 12 | </buildCommand> |
13 | - <buildCommand> | |
14 | - <name>org.eclipse.m2e.core.maven2Builder</name> | |
15 | - <arguments> | |
16 | - </arguments> | |
17 | - </buildCommand> | |
18 | 13 | </buildSpec> |
19 | 14 | <natures> |
15 | + <nature>org.springsource.ide.eclipse.gradle.core.nature</nature> | |
20 | 16 | <nature>org.eclipse.jdt.core.javanature</nature> |
21 | - <nature>org.eclipse.m2e.core.maven2Nature</nature> | |
22 | 17 | </natures> |
23 | 18 | </projectDescription> |
@@ -0,0 +1,41 @@ | ||
1 | +apply plugin: 'java' | |
2 | +apply plugin: 'eclipse' | |
3 | + | |
4 | +sourceCompatibility = 1.5 | |
5 | +version = '1.0' | |
6 | +jar { | |
7 | + manifest { | |
8 | + attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version | |
9 | + } | |
10 | +} | |
11 | + | |
12 | +repositories { | |
13 | + mavenCentral() | |
14 | +} | |
15 | + | |
16 | +dependencies { | |
17 | + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' | |
18 | + compile group: 'net.sf.opencsv', name: 'opencsv', version: '2.3' | |
19 | + compile group: 'xstream', name: 'xstream', version: '1.2.2' | |
20 | + compile group: 'org.rxtx', name: 'rxtx', version: '2.1.7' | |
21 | + testCompile group: 'junit', name: 'junit', version: '4.+' | |
22 | + compile project(':../TunnelSerialToIEEE1888') | |
23 | + compile project(':../mirrg.serial.fluorine') | |
24 | + compile project(':../mirrg.swing.helium') | |
25 | + compile project(':../jp.hishidama') | |
26 | +} | |
27 | + | |
28 | +test { | |
29 | + systemProperties 'property': 'value' | |
30 | +} | |
31 | + | |
32 | +uploadArchives { | |
33 | + repositories { | |
34 | + flatDir { | |
35 | + dirs 'repos' | |
36 | + } | |
37 | + } | |
38 | +} | |
39 | + | |
40 | +tasks.withType(AbstractCompile)*.options*.encoding = tasks.withType(GroovyCompile)*.groovyOptions*.encoding = 'UTF-8' | |
41 | +sourceCompatibility = targetCompatibility = '1.8' |
@@ -1,39 +0,0 @@ | ||
1 | -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
2 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
3 | - <modelVersion>4.0.0</modelVersion> | |
4 | - | |
5 | - <groupId>jp.ac.kisarazu.j.kurilab</groupId> | |
6 | - <artifactId>ChlorophyllUploader</artifactId> | |
7 | - <version>0.0.1-SNAPSHOT</version> | |
8 | - <packaging>jar</packaging> | |
9 | - | |
10 | - <name>cf-uploader</name> | |
11 | - <url>http://maven.apache.org</url> | |
12 | - | |
13 | - <properties> | |
14 | - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
15 | - </properties> | |
16 | - | |
17 | - <dependencies> | |
18 | - <dependency> | |
19 | - <groupId>junit</groupId> | |
20 | - <artifactId>junit</artifactId> | |
21 | - <version>4.12</version> | |
22 | - <scope>test</scope> | |
23 | - </dependency> | |
24 | - <dependency> | |
25 | - <groupId>net.sf.opencsv</groupId> | |
26 | - <artifactId>opencsv</artifactId> | |
27 | - <version>2.3</version> | |
28 | - </dependency> | |
29 | - <dependency> | |
30 | - <groupId>xstream</groupId> | |
31 | - <artifactId>xstream</artifactId> | |
32 | - <version>1.2.2</version> | |
33 | - </dependency><dependency> | |
34 | - <groupId>org.rxtx</groupId> | |
35 | - <artifactId>rxtx</artifactId> | |
36 | - <version>2.1.7</version> | |
37 | - </dependency> | |
38 | - </dependencies> | |
39 | -</project> |
@@ -0,0 +1,4 @@ | ||
1 | +include '../TunnelSerialToIEEE1888' | |
2 | +include '../mirrg.serial.fluorine' | |
3 | +include '../mirrg.swing.helium' | |
4 | +include '../jp.hishidama' | |
\ No newline at end of file |
@@ -1,27 +1,10 @@ | ||
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <classpath> |
3 | - <classpathentry kind="src" output="target/classes" path="src/main/java"> | |
4 | - <attributes> | |
5 | - <attribute name="optional" value="true"/> | |
6 | - <attribute name="maven.pomderived" value="true"/> | |
7 | - </attributes> | |
8 | - </classpathentry> | |
9 | - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |
10 | - <attributes> | |
11 | - <attribute name="optional" value="true"/> | |
12 | - <attribute name="maven.pomderived" value="true"/> | |
13 | - </attributes> | |
14 | - </classpathentry> | |
15 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |
16 | - <attributes> | |
17 | - <attribute name="maven.pomderived" value="true"/> | |
18 | - </attributes> | |
19 | - </classpathentry> | |
20 | - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |
21 | - <attributes> | |
22 | - <attribute name="maven.pomderived" value="true"/> | |
23 | - </attributes> | |
24 | - </classpathentry> | |
25 | - <classpathentry combineaccessrules="false" kind="src" path="/mirrg.serial.fluorine"/> | |
26 | - <classpathentry kind="output" path="target/classes"/> | |
3 | + <classpathentry kind="src" path="src/main/java"/> | |
4 | + <classpathentry kind="src" path="src/main/resources"/> | |
5 | + <classpathentry kind="src" path="src/test/java"/> | |
6 | + <classpathentry kind="src" path="src/test/resources"/> | |
7 | + <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |
8 | + <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/> | |
9 | + <classpathentry kind="output" path="bin"/> | |
27 | 10 | </classpath> |
@@ -10,14 +10,9 @@ | ||
10 | 10 | <arguments> |
11 | 11 | </arguments> |
12 | 12 | </buildCommand> |
13 | - <buildCommand> | |
14 | - <name>org.eclipse.m2e.core.maven2Builder</name> | |
15 | - <arguments> | |
16 | - </arguments> | |
17 | - </buildCommand> | |
18 | 13 | </buildSpec> |
19 | 14 | <natures> |
15 | + <nature>org.springsource.ide.eclipse.gradle.core.nature</nature> | |
20 | 16 | <nature>org.eclipse.jdt.core.javanature</nature> |
21 | - <nature>org.eclipse.m2e.core.maven2Nature</nature> | |
22 | 17 | </natures> |
23 | 18 | </projectDescription> |
@@ -0,0 +1,35 @@ | ||
1 | +apply plugin: 'java' | |
2 | +apply plugin: 'eclipse' | |
3 | + | |
4 | +sourceCompatibility = 1.5 | |
5 | +version = '1.0' | |
6 | +jar { | |
7 | + manifest { | |
8 | + attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version | |
9 | + } | |
10 | +} | |
11 | + | |
12 | +repositories { | |
13 | + mavenCentral() | |
14 | +} | |
15 | + | |
16 | +dependencies { | |
17 | + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' | |
18 | + testCompile group: 'junit', name: 'junit', version: '4.+' | |
19 | + compile project(':../mirrg.serial.fluorine') | |
20 | +} | |
21 | + | |
22 | +test { | |
23 | + systemProperties 'property': 'value' | |
24 | +} | |
25 | + | |
26 | +uploadArchives { | |
27 | + repositories { | |
28 | + flatDir { | |
29 | + dirs 'repos' | |
30 | + } | |
31 | + } | |
32 | +} | |
33 | + | |
34 | +tasks.withType(AbstractCompile)*.options*.encoding = tasks.withType(GroovyCompile)*.groovyOptions*.encoding = 'UTF-8' | |
35 | +sourceCompatibility = targetCompatibility = '1.8' |
@@ -1,25 +0,0 @@ | ||
1 | -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
2 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
3 | - <modelVersion>4.0.0</modelVersion> | |
4 | - | |
5 | - <groupId>jp.ac.kisarazu.j.kurilab</groupId> | |
6 | - <artifactId>TunnelSerialToIEEE1888</artifactId> | |
7 | - <version>0.0.1-SNAPSHOT</version> | |
8 | - <packaging>jar</packaging> | |
9 | - | |
10 | - <name>TunnelSerialToIEEE1888</name> | |
11 | - <url>http://maven.apache.org</url> | |
12 | - | |
13 | - <properties> | |
14 | - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
15 | - </properties> | |
16 | - | |
17 | - <dependencies> | |
18 | - <dependency> | |
19 | - <groupId>junit</groupId> | |
20 | - <artifactId>junit</artifactId> | |
21 | - <version>4.12</version> | |
22 | - <scope>test</scope> | |
23 | - </dependency> | |
24 | - </dependencies> | |
25 | -</project> |
@@ -0,0 +1,1 @@ | ||
1 | +include '../mirrg.serial.fluorine' | |
\ No newline at end of file |
@@ -1,10 +1,10 @@ | ||
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <classpath> |
3 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | |
4 | - <classpathentry kind="src" path="src"> | |
5 | - <attributes> | |
6 | - <attribute name="ignore_optional_problems" value="true"/> | |
7 | - </attributes> | |
8 | - </classpathentry> | |
3 | + <classpathentry kind="src" path="src/main/java"/> | |
4 | + <classpathentry kind="src" path="src/main/resources"/> | |
5 | + <classpathentry kind="src" path="src/test/java"/> | |
6 | + <classpathentry kind="src" path="src/test/resources"/> | |
7 | + <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |
8 | + <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/> | |
9 | 9 | <classpathentry kind="output" path="bin"/> |
10 | 10 | </classpath> |
@@ -12,6 +12,7 @@ | ||
12 | 12 | </buildCommand> |
13 | 13 | </buildSpec> |
14 | 14 | <natures> |
15 | + <nature>org.springsource.ide.eclipse.gradle.core.nature</nature> | |
15 | 16 | <nature>org.eclipse.jdt.core.javanature</nature> |
16 | 17 | </natures> |
17 | 18 | </projectDescription> |
@@ -1,26 +1,10 @@ | ||
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <classpath> |
3 | - <classpathentry kind="src" output="target/classes" path="src/main/java"> | |
4 | - <attributes> | |
5 | - <attribute name="optional" value="true"/> | |
6 | - <attribute name="maven.pomderived" value="true"/> | |
7 | - </attributes> | |
8 | - </classpathentry> | |
9 | - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |
10 | - <attributes> | |
11 | - <attribute name="optional" value="true"/> | |
12 | - <attribute name="maven.pomderived" value="true"/> | |
13 | - </attributes> | |
14 | - </classpathentry> | |
15 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |
16 | - <attributes> | |
17 | - <attribute name="maven.pomderived" value="true"/> | |
18 | - </attributes> | |
19 | - </classpathentry> | |
20 | - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |
21 | - <attributes> | |
22 | - <attribute name="maven.pomderived" value="true"/> | |
23 | - </attributes> | |
24 | - </classpathentry> | |
25 | - <classpathentry kind="output" path="target/classes"/> | |
3 | + <classpathentry kind="src" path="src/main/java"/> | |
4 | + <classpathentry kind="src" path="src/main/resources"/> | |
5 | + <classpathentry kind="src" path="src/test/java"/> | |
6 | + <classpathentry kind="src" path="src/test/resources"/> | |
7 | + <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |
8 | + <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/> | |
9 | + <classpathentry kind="output" path="bin"/> | |
26 | 10 | </classpath> |
@@ -10,14 +10,9 @@ | ||
10 | 10 | <arguments> |
11 | 11 | </arguments> |
12 | 12 | </buildCommand> |
13 | - <buildCommand> | |
14 | - <name>org.eclipse.m2e.core.maven2Builder</name> | |
15 | - <arguments> | |
16 | - </arguments> | |
17 | - </buildCommand> | |
18 | 13 | </buildSpec> |
19 | 14 | <natures> |
15 | + <nature>org.springsource.ide.eclipse.gradle.core.nature</nature> | |
20 | 16 | <nature>org.eclipse.jdt.core.javanature</nature> |
21 | - <nature>org.eclipse.m2e.core.maven2Nature</nature> | |
22 | 17 | </natures> |
23 | 18 | </projectDescription> |
@@ -0,0 +1,34 @@ | ||
1 | +apply plugin: 'java' | |
2 | +apply plugin: 'eclipse' | |
3 | + | |
4 | +sourceCompatibility = 1.5 | |
5 | +version = '1.0' | |
6 | +jar { | |
7 | + manifest { | |
8 | + attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version | |
9 | + } | |
10 | +} | |
11 | + | |
12 | +repositories { | |
13 | + mavenCentral() | |
14 | +} | |
15 | + | |
16 | +dependencies { | |
17 | + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' | |
18 | + compile group: 'junit', name: 'junit', version: '4.+' | |
19 | +} | |
20 | + | |
21 | +test { | |
22 | + systemProperties 'property': 'value' | |
23 | +} | |
24 | + | |
25 | +uploadArchives { | |
26 | + repositories { | |
27 | + flatDir { | |
28 | + dirs 'repos' | |
29 | + } | |
30 | + } | |
31 | +} | |
32 | + | |
33 | +tasks.withType(AbstractCompile)*.options*.encoding = tasks.withType(GroovyCompile)*.groovyOptions*.encoding = 'UTF-8' | |
34 | +sourceCompatibility = targetCompatibility = '1.8' |
@@ -1,25 +0,0 @@ | ||
1 | -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
2 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
3 | - <modelVersion>4.0.0</modelVersion> | |
4 | - | |
5 | - <groupId>mirrg</groupId> | |
6 | - <artifactId>mirrg.serial.fluorine</artifactId> | |
7 | - <version>0.0.1-SNAPSHOT</version> | |
8 | - <packaging>jar</packaging> | |
9 | - | |
10 | - <name>cf-serial-framework</name> | |
11 | - <url>http://maven.apache.org</url> | |
12 | - | |
13 | - <properties> | |
14 | - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
15 | - </properties> | |
16 | - | |
17 | - <dependencies> | |
18 | - <dependency> | |
19 | - <groupId>junit</groupId> | |
20 | - <artifactId>junit</artifactId> | |
21 | - <version>4.12</version> | |
22 | - <scope>test</scope> | |
23 | - </dependency> | |
24 | - </dependencies> | |
25 | -</project> |
@@ -1,7 +1,10 @@ | ||
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <classpath> |
3 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | |
4 | - <classpathentry kind="src" path="mirrg.swing.helium"/> | |
5 | - <classpathentry kind="lib" path="mirrg.struct.hydrogen-20150715.jar"/> | |
3 | + <classpathentry kind="src" path="src/main/java"/> | |
4 | + <classpathentry kind="src" path="src/main/resources"/> | |
5 | + <classpathentry kind="src" path="src/test/java"/> | |
6 | + <classpathentry kind="src" path="src/test/resources"/> | |
7 | + <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |
8 | + <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/> | |
6 | 9 | <classpathentry kind="output" path="bin"/> |
7 | 10 | </classpath> |
@@ -12,6 +12,7 @@ | ||
12 | 12 | </buildCommand> |
13 | 13 | </buildSpec> |
14 | 14 | <natures> |
15 | + <nature>org.springsource.ide.eclipse.gradle.core.nature</nature> | |
15 | 16 | <nature>org.eclipse.jdt.core.javanature</nature> |
16 | 17 | </natures> |
17 | 18 | </projectDescription> |
@@ -0,0 +1,35 @@ | ||
1 | +apply plugin: 'java' | |
2 | +apply plugin: 'eclipse' | |
3 | + | |
4 | +sourceCompatibility = 1.5 | |
5 | +version = '1.0' | |
6 | +jar { | |
7 | + manifest { | |
8 | + attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version | |
9 | + } | |
10 | +} | |
11 | + | |
12 | +repositories { | |
13 | + mavenCentral() | |
14 | +} | |
15 | + | |
16 | +dependencies { | |
17 | + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' | |
18 | + testCompile group: 'junit', name: 'junit', version: '4.+' | |
19 | + compile files('mirrg.struct.hydrogen-20150715.jar') | |
20 | +} | |
21 | + | |
22 | +test { | |
23 | + systemProperties 'property': 'value' | |
24 | +} | |
25 | + | |
26 | +uploadArchives { | |
27 | + repositories { | |
28 | + flatDir { | |
29 | + dirs 'repos' | |
30 | + } | |
31 | + } | |
32 | +} | |
33 | + | |
34 | +tasks.withType(AbstractCompile)*.options*.encoding = tasks.withType(GroovyCompile)*.groovyOptions*.encoding = 'UTF-8' | |
35 | +sourceCompatibility = targetCompatibility = '1.8' |
@@ -1,314 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import java.awt.Component; | |
4 | -import java.awt.Dimension; | |
5 | -import java.awt.event.KeyEvent; | |
6 | -import java.awt.event.KeyListener; | |
7 | -import java.beans.PropertyChangeListener; | |
8 | -import java.io.IOException; | |
9 | -import java.net.URL; | |
10 | -import java.util.LinkedList; | |
11 | - | |
12 | -import javax.swing.GroupLayout; | |
13 | -import javax.swing.GroupLayout.Alignment; | |
14 | -import javax.swing.JButton; | |
15 | -import javax.swing.JEditorPane; | |
16 | -import javax.swing.JLabel; | |
17 | -import javax.swing.JMenuItem; | |
18 | -import javax.swing.JPopupMenu; | |
19 | -import javax.swing.JScrollPane; | |
20 | -import javax.swing.JTextField; | |
21 | -import javax.swing.event.HyperlinkEvent.EventType; | |
22 | -import javax.swing.text.Document; | |
23 | -import javax.swing.text.html.HTMLDocument; | |
24 | - | |
25 | -import mirrg.struct.hydrogen.Struct1; | |
26 | -import mirrg.struct.hydrogen.Tuple; | |
27 | -import mirrg.swing.helium.logging.EnumTypeLog; | |
28 | -import mirrg.swing.helium.logging.HLog; | |
29 | - | |
30 | -public class FrameHTML extends FrameMirrg | |
31 | -{ | |
32 | - | |
33 | - /** | |
34 | - * 下に行くほど新しい。 | |
35 | - */ | |
36 | - private LinkedList<Tuple<URL, Integer>> historyLeft = new LinkedList<>(); | |
37 | - /** | |
38 | - * 下に行くほど新しい。 | |
39 | - */ | |
40 | - private LinkedList<Tuple<URL, Integer>> historyRight = new LinkedList<>(); | |
41 | - | |
42 | - private JButton button1; | |
43 | - private JButton button2; | |
44 | - private JTextField textField1; | |
45 | - private JEditorPane editorPane1; | |
46 | - private JScrollPane scrollPane1; | |
47 | - | |
48 | - public FrameHTML() | |
49 | - { | |
50 | - setTitle("HTMLビューワ"); | |
51 | - | |
52 | - { | |
53 | - | |
54 | - button1 = new JButton("戻る"); | |
55 | - button1.setToolTipText("右クリック:プルダウンメニューの表示"); | |
56 | - button1.addActionListener(e -> { | |
57 | - if (!historyLeft.isEmpty()) travelLeft(1); | |
58 | - }); | |
59 | - HSwing.hookPopup(button1, e -> { | |
60 | - | |
61 | - if (!historyLeft.isEmpty()) { | |
62 | - JPopupMenu popupMenu = new JPopupMenu(); | |
63 | - | |
64 | - for (int i = historyLeft.size() - 1; i >= 0; i--) { | |
65 | - Tuple<URL, Integer> entry = historyLeft.get(i); | |
66 | - JMenuItem menuItem = new JMenuItem( | |
67 | - entry.getY().toString() + ": " + entry.getX().toString()); | |
68 | - popupMenu.add(menuItem); | |
69 | - | |
70 | - int i2 = i + 1; | |
71 | - menuItem.addActionListener(e2 -> { | |
72 | - travelLeft(i2); | |
73 | - }); | |
74 | - } | |
75 | - | |
76 | - popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); | |
77 | - | |
78 | - return true; | |
79 | - } | |
80 | - | |
81 | - return false; | |
82 | - }); | |
83 | - | |
84 | - button2 = new JButton("進む"); | |
85 | - button2.setToolTipText("右クリック:プルダウンメニューの表示"); | |
86 | - button2.addActionListener(e -> { | |
87 | - if (!historyRight.isEmpty()) travelRight(1); | |
88 | - }); | |
89 | - HSwing.hookPopup(button2, e -> { | |
90 | - | |
91 | - if (!historyRight.isEmpty()) { | |
92 | - JPopupMenu popupMenu = new JPopupMenu(); | |
93 | - | |
94 | - for (int i = 0; i < historyRight.size(); i++) { | |
95 | - Tuple<URL, Integer> entry = historyRight.get(i); | |
96 | - JMenuItem menuItem = new JMenuItem( | |
97 | - entry.getY().toString() + ": " + entry.getX().toString()); | |
98 | - popupMenu.add(menuItem); | |
99 | - | |
100 | - int i2 = i + 1; | |
101 | - menuItem.addActionListener(e2 -> { | |
102 | - travelRight(i2); | |
103 | - }); | |
104 | - } | |
105 | - | |
106 | - popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); | |
107 | - | |
108 | - return true; | |
109 | - } | |
110 | - | |
111 | - return false; | |
112 | - }); | |
113 | - | |
114 | - textField1 = new JTextField(); | |
115 | - textField1.addActionListener(e -> { | |
116 | - navigate(textField1.getText()); | |
117 | - }); | |
118 | - | |
119 | - JButton button3 = new JButton("移動"); | |
120 | - button3.addActionListener(e -> { | |
121 | - navigate(textField1.getText()); | |
122 | - }); | |
123 | - | |
124 | - JButton button4 = new JButton("更新"); | |
125 | - button4.addActionListener(e -> { | |
126 | - refresh(); | |
127 | - }); | |
128 | - | |
129 | - editorPane1 = new JEditorPane(); | |
130 | - editorPane1.setEditable(false); | |
131 | - editorPane1.addHyperlinkListener(e -> { | |
132 | - if (e.getEventType() == EventType.ACTIVATED) { | |
133 | - navigate(e.getURL()); | |
134 | - } | |
135 | - }); | |
136 | - editorPane1.addKeyListener(new KeyListener() { | |
137 | - | |
138 | - @Override | |
139 | - public void keyTyped(KeyEvent e) | |
140 | - { | |
141 | - | |
142 | - } | |
143 | - | |
144 | - @Override | |
145 | - public void keyReleased(KeyEvent e) | |
146 | - { | |
147 | - | |
148 | - } | |
149 | - | |
150 | - @Override | |
151 | - public void keyPressed(KeyEvent e) | |
152 | - { | |
153 | - if (e.getKeyCode() == KeyEvent.VK_F5) { | |
154 | - refresh(); | |
155 | - return; | |
156 | - } | |
157 | - if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) { | |
158 | - if (!historyLeft.isEmpty()) travelLeft(1); | |
159 | - return; | |
160 | - } | |
161 | - } | |
162 | - | |
163 | - }); | |
164 | - | |
165 | - scrollPane1 = new JScrollPane(editorPane1); | |
166 | - scrollPane1.setPreferredSize(new Dimension(800, 800)); | |
167 | - | |
168 | - { | |
169 | - GroupLayout layout = new GroupLayout(getContentPane()); | |
170 | - setLayout(layout); | |
171 | - | |
172 | - layout.setAutoCreateGaps(true); | |
173 | - layout.setAutoCreateContainerGaps(false); | |
174 | - | |
175 | - GroupBuilder.group( | |
176 | - GroupBuilder.group( | |
177 | - button1, | |
178 | - button2, | |
179 | - new JLabel("アドレス:"), | |
180 | - textField1, | |
181 | - button3, | |
182 | - button4 | |
183 | - ).align(Alignment.CENTER), | |
184 | - scrollPane1 | |
185 | - ).apply(layout); | |
186 | - } | |
187 | - } | |
188 | - | |
189 | - historyChanged(); | |
190 | - | |
191 | - HLog.log(EnumTypeLog.FINE, "HTMLビューワを起動しました"); | |
192 | - | |
193 | - prepareFrame(); | |
194 | - } | |
195 | - | |
196 | - private void refresh() | |
197 | - { | |
198 | - Tuple<URL, Integer> now = getNow(); | |
199 | - | |
200 | - ((HTMLDocument) editorPane1.getDocument()).getDocumentProperties().remove( | |
201 | - Document.StreamDescriptionProperty); | |
202 | - | |
203 | - if (now != null) setPage(now); | |
204 | - } | |
205 | - | |
206 | - private Tuple<URL, Integer> getNow() | |
207 | - { | |
208 | - URL page = editorPane1.getPage(); | |
209 | - | |
210 | - return page == null | |
211 | - ? null | |
212 | - : new Tuple<>(page, scrollPane1.getVerticalScrollBar().getValue()); | |
213 | - } | |
214 | - | |
215 | - private void travelLeft(int times) | |
216 | - { | |
217 | - Tuple<URL, Integer> now = getNow(); | |
218 | - | |
219 | - // 履歴操作 | |
220 | - for (int i = 0; i < times; i++) { | |
221 | - historyRight.addFirst(now); | |
222 | - now = historyLeft.removeLast(); | |
223 | - } | |
224 | - | |
225 | - historyChanged(); | |
226 | - | |
227 | - setPage(now); | |
228 | - } | |
229 | - | |
230 | - private void travelRight(int times) | |
231 | - { | |
232 | - Tuple<URL, Integer> now = getNow(); | |
233 | - | |
234 | - // 履歴操作 | |
235 | - for (int i = 0; i < times; i++) { | |
236 | - historyLeft.addLast(now); | |
237 | - now = historyRight.removeFirst(); | |
238 | - } | |
239 | - | |
240 | - historyChanged(); | |
241 | - | |
242 | - setPage(now); | |
243 | - } | |
244 | - | |
245 | - private void setPage(Tuple<URL, Integer> url) | |
246 | - { | |
247 | - try { | |
248 | - editorPane1.setPage(url.getX()); | |
249 | - } catch (IOException e) { | |
250 | - HLog.processExceptionWarning(e); | |
251 | - return; | |
252 | - } | |
253 | - | |
254 | - textField1.setText(url.getX().toString()); | |
255 | - | |
256 | - // 表示位置調整 | |
257 | - Struct1<PropertyChangeListener> listener = new Struct1<>(); | |
258 | - listener.x = e -> { | |
259 | - editorPane1.removePropertyChangeListener("page", listener.x); | |
260 | - | |
261 | - scrollPane1.getVerticalScrollBar().setValue(url.getY()); | |
262 | - | |
263 | - }; | |
264 | - editorPane1.addPropertyChangeListener("page", listener.x); | |
265 | - | |
266 | - // 同じページに遷移した場合にイベントが発生しないので念のために変更しておく | |
267 | - // TODO イベントが残留するが次のイベントで死ぬのでとりあえず良しとする | |
268 | - scrollPane1.getVerticalScrollBar().setValue(url.getY()); | |
269 | - | |
270 | - } | |
271 | - | |
272 | - public void navigate(String url) | |
273 | - { | |
274 | - Tuple<URL, Integer> now = getNow(); | |
275 | - if (now != null) { | |
276 | - historyLeft.addLast(now); | |
277 | - historyChanged(); | |
278 | - } | |
279 | - | |
280 | - try { | |
281 | - editorPane1.setPage(url); | |
282 | - } catch (IOException e) { | |
283 | - HLog.processExceptionWarning(e); | |
284 | - return; | |
285 | - } | |
286 | - | |
287 | - textField1.setText(url); | |
288 | - } | |
289 | - | |
290 | - public void navigate(URL url) | |
291 | - { | |
292 | - Tuple<URL, Integer> now = getNow(); | |
293 | - if (now != null) { | |
294 | - historyLeft.addLast(now); | |
295 | - historyChanged(); | |
296 | - } | |
297 | - | |
298 | - try { | |
299 | - editorPane1.setPage(url); | |
300 | - } catch (IOException e) { | |
301 | - HLog.processExceptionWarning(e); | |
302 | - return; | |
303 | - } | |
304 | - | |
305 | - textField1.setText(url.toString()); | |
306 | - } | |
307 | - | |
308 | - private void historyChanged() | |
309 | - { | |
310 | - button1.setEnabled(!historyLeft.isEmpty()); | |
311 | - button2.setEnabled(!historyRight.isEmpty()); | |
312 | - } | |
313 | - | |
314 | -} |
@@ -1,205 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import java.awt.GraphicsConfiguration; | |
4 | -import java.awt.HeadlessException; | |
5 | -import java.awt.event.ComponentEvent; | |
6 | -import java.awt.event.ComponentListener; | |
7 | -import java.awt.event.WindowEvent; | |
8 | -import java.awt.event.WindowListener; | |
9 | -import java.util.ArrayList; | |
10 | -import java.util.function.Consumer; | |
11 | - | |
12 | -import javax.swing.JFrame; | |
13 | -import javax.swing.WindowConstants; | |
14 | - | |
15 | -public class FrameMirrg extends JFrame | |
16 | -{ | |
17 | - | |
18 | - public FrameMirrg() throws HeadlessException | |
19 | - { | |
20 | - super(); | |
21 | - initFrameMirrg(); | |
22 | - } | |
23 | - | |
24 | - public FrameMirrg(GraphicsConfiguration gc) | |
25 | - { | |
26 | - super(gc); | |
27 | - initFrameMirrg(); | |
28 | - } | |
29 | - | |
30 | - public FrameMirrg(String title) throws HeadlessException | |
31 | - { | |
32 | - super(title); | |
33 | - initFrameMirrg(); | |
34 | - } | |
35 | - | |
36 | - public FrameMirrg(String title, GraphicsConfiguration gc) | |
37 | - { | |
38 | - super(title, gc); | |
39 | - initFrameMirrg(); | |
40 | - } | |
41 | - | |
42 | - //////////////////////////////////////////////// | |
43 | - | |
44 | - private ArrayList<Consumer<WindowEvent>> listenersOnInitialized = new ArrayList<>(); | |
45 | - private ArrayList<Consumer<ComponentEvent>> listenersOnShown = new ArrayList<>(); | |
46 | - private ArrayList<Consumer<ComponentEvent>> listenersOnHidden = new ArrayList<>(); | |
47 | - private ArrayList<Consumer<WindowEvent>> listenersOnDisposed = new ArrayList<>(); | |
48 | - | |
49 | - /** | |
50 | - * 初回open時 | |
51 | - */ | |
52 | - public void hookInitialized(Consumer<WindowEvent> listener) | |
53 | - { | |
54 | - listenersOnInitialized.add(listener); | |
55 | - } | |
56 | - | |
57 | - /** | |
58 | - * 初回も含めてウィンドウが開くとき | |
59 | - */ | |
60 | - public void hookShown(Consumer<ComponentEvent> listener) | |
61 | - { | |
62 | - listenersOnShown.add(listener); | |
63 | - } | |
64 | - | |
65 | - /** | |
66 | - * disposeも含めてウィンドウが閉じるとき | |
67 | - */ | |
68 | - public void hookHidden(Consumer<ComponentEvent> listener) | |
69 | - { | |
70 | - listenersOnHidden.add(listener); | |
71 | - } | |
72 | - | |
73 | - /** | |
74 | - * disposeするとき | |
75 | - */ | |
76 | - public void hookDisposed(Consumer<WindowEvent> listener) | |
77 | - { | |
78 | - listenersOnDisposed.add(listener); | |
79 | - } | |
80 | - | |
81 | - //////////////////////////////////////////////// | |
82 | - | |
83 | - private boolean visible = false; | |
84 | - | |
85 | - private void initFrameMirrg() | |
86 | - { | |
87 | - addComponentListener(new ComponentListener() { | |
88 | - | |
89 | - @Override | |
90 | - public void componentShown(ComponentEvent e) | |
91 | - { | |
92 | - visible = true; | |
93 | - | |
94 | - listenersOnShown.forEach(listener -> { | |
95 | - listener.accept(e); | |
96 | - }); | |
97 | - } | |
98 | - | |
99 | - @Override | |
100 | - public void componentResized(ComponentEvent e) | |
101 | - { | |
102 | - | |
103 | - } | |
104 | - | |
105 | - @Override | |
106 | - public void componentMoved(ComponentEvent e) | |
107 | - { | |
108 | - | |
109 | - } | |
110 | - | |
111 | - @Override | |
112 | - public void componentHidden(ComponentEvent e) | |
113 | - { | |
114 | - visible = false; | |
115 | - | |
116 | - listenersOnHidden.forEach(listener -> { | |
117 | - listener.accept(e); | |
118 | - }); | |
119 | - } | |
120 | - | |
121 | - }); | |
122 | - addWindowListener(new WindowListener() { | |
123 | - | |
124 | - @Override | |
125 | - public void windowOpened(WindowEvent e) | |
126 | - { | |
127 | - listenersOnInitialized.forEach(listener -> { | |
128 | - listener.accept(e); | |
129 | - }); | |
130 | - } | |
131 | - | |
132 | - @Override | |
133 | - public void windowIconified(WindowEvent e) | |
134 | - { | |
135 | - | |
136 | - } | |
137 | - | |
138 | - @Override | |
139 | - public void windowDeiconified(WindowEvent e) | |
140 | - { | |
141 | - | |
142 | - } | |
143 | - | |
144 | - @Override | |
145 | - public void windowDeactivated(WindowEvent e) | |
146 | - { | |
147 | - | |
148 | - } | |
149 | - | |
150 | - @Override | |
151 | - public void windowClosing(WindowEvent e) | |
152 | - { | |
153 | - | |
154 | - } | |
155 | - | |
156 | - @Override | |
157 | - public void windowClosed(WindowEvent e) | |
158 | - { | |
159 | - if (visible) { | |
160 | - listenersOnHidden.forEach(listener -> { | |
161 | - listener.accept(e); | |
162 | - }); | |
163 | - } | |
164 | - listenersOnDisposed.forEach(listener -> { | |
165 | - listener.accept(e); | |
166 | - }); | |
167 | - } | |
168 | - | |
169 | - @Override | |
170 | - public void windowActivated(WindowEvent e) | |
171 | - { | |
172 | - | |
173 | - } | |
174 | - | |
175 | - }); | |
176 | - } | |
177 | - | |
178 | - private volatile boolean isDisposed = false; | |
179 | - | |
180 | - /** | |
181 | - * スレッドセーフ | |
182 | - */ | |
183 | - public boolean isDisposed() | |
184 | - { | |
185 | - return isDisposed; | |
186 | - } | |
187 | - | |
188 | - @Override | |
189 | - public void dispose() | |
190 | - { | |
191 | - isDisposed = true; | |
192 | - super.dispose(); | |
193 | - } | |
194 | - | |
195 | - //////////////////////////////////////////////// | |
196 | - | |
197 | - public void prepareFrame() | |
198 | - { | |
199 | - setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); | |
200 | - | |
201 | - pack(); | |
202 | - setLocationByPlatform(true); | |
203 | - } | |
204 | - | |
205 | -} |
@@ -1,63 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import java.awt.Component; | |
4 | - | |
5 | -import javax.swing.GroupLayout; | |
6 | -import javax.swing.GroupLayout.Alignment; | |
7 | -import javax.swing.GroupLayout.Group; | |
8 | - | |
9 | -public class GroupBuilder | |
10 | -{ | |
11 | - | |
12 | - public static GroupBuilder group(Object... objects) | |
13 | - { | |
14 | - return new GroupBuilder(objects); | |
15 | - } | |
16 | - | |
17 | - private Object[] objects; | |
18 | - private Alignment alignment = null; | |
19 | - | |
20 | - public GroupBuilder(Object[] objects) | |
21 | - { | |
22 | - this.objects = objects; | |
23 | - } | |
24 | - | |
25 | - public Group build(GroupLayout groupLayout) | |
26 | - { | |
27 | - return build(groupLayout, true); | |
28 | - } | |
29 | - | |
30 | - public Group build(GroupLayout groupLayout, boolean isSequential) | |
31 | - { | |
32 | - Group group = isSequential | |
33 | - ? groupLayout.createSequentialGroup() | |
34 | - : alignment != null | |
35 | - ? groupLayout.createParallelGroup(alignment) | |
36 | - : groupLayout.createParallelGroup(); | |
37 | - | |
38 | - for (Object object : objects) { | |
39 | - if (object instanceof GroupBuilder) { | |
40 | - group.addGroup(((GroupBuilder) object).build(groupLayout, !isSequential)); | |
41 | - } else if (object instanceof Component) { | |
42 | - group.addComponent((Component) object); | |
43 | - } else { | |
44 | - throw new RuntimeException("unknown group build entry: " + object); | |
45 | - } | |
46 | - } | |
47 | - | |
48 | - return group; | |
49 | - } | |
50 | - | |
51 | - public void apply(GroupLayout layout) | |
52 | - { | |
53 | - layout.setHorizontalGroup(build(layout, false)); | |
54 | - layout.setVerticalGroup(build(layout)); | |
55 | - } | |
56 | - | |
57 | - public GroupBuilder align(Alignment alignment) | |
58 | - { | |
59 | - this.alignment = alignment; | |
60 | - return this; | |
61 | - } | |
62 | - | |
63 | -} |
@@ -1,216 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import java.awt.Component; | |
4 | -import java.awt.Font; | |
5 | -import java.awt.event.MouseEvent; | |
6 | -import java.awt.event.MouseListener; | |
7 | -import java.lang.reflect.Field; | |
8 | -import java.util.function.Consumer; | |
9 | -import java.util.function.Predicate; | |
10 | -import java.util.regex.Pattern; | |
11 | - | |
12 | -import javax.swing.UIManager; | |
13 | -import javax.swing.UIManager.LookAndFeelInfo; | |
14 | -import javax.swing.UnsupportedLookAndFeelException; | |
15 | -import javax.swing.event.DocumentEvent; | |
16 | -import javax.swing.event.DocumentListener; | |
17 | -import javax.swing.text.JTextComponent; | |
18 | - | |
19 | -public class HSwing | |
20 | -{ | |
21 | - | |
22 | - public static void setWindowsLookAndFeel() | |
23 | - { | |
24 | - try { | |
25 | - UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); | |
26 | - } catch (ClassNotFoundException e) { | |
27 | - e.printStackTrace(); | |
28 | - } catch (InstantiationException e) { | |
29 | - e.printStackTrace(); | |
30 | - } catch (IllegalAccessException e) { | |
31 | - e.printStackTrace(); | |
32 | - } catch (UnsupportedLookAndFeelException e) { | |
33 | - e.printStackTrace(); | |
34 | - } | |
35 | - } | |
36 | - | |
37 | - public static boolean tryAddWebLookAndFeel() | |
38 | - { | |
39 | - try { | |
40 | - Class<?> clazz = Class.forName("com.alee.laf.WebLookAndFeel"); | |
41 | - if (clazz != null) { | |
42 | - | |
43 | - Field[] fields = clazz.getFields(); | |
44 | - | |
45 | - Pattern pattern = Pattern.compile("global[\\w\\d_]*Font"); | |
46 | - Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 12); | |
47 | - | |
48 | - for (Field field : fields) { | |
49 | - if (pattern.matcher(field.getName()).matches()) { | |
50 | - if (field.getType().isInstance(font)) { | |
51 | - try { | |
52 | - field.set(null, font); | |
53 | - } catch (IllegalArgumentException e) { | |
54 | - e.printStackTrace(); | |
55 | - } catch (IllegalAccessException e) { | |
56 | - e.printStackTrace(); | |
57 | - } | |
58 | - } | |
59 | - } | |
60 | - } | |
61 | - | |
62 | - UIManager.installLookAndFeel(new LookAndFeelInfo(clazz.getSimpleName(), clazz.getName())); | |
63 | - | |
64 | - } | |
65 | - | |
66 | - return true; | |
67 | - } catch (ClassNotFoundException e) { | |
68 | - return false; | |
69 | - } | |
70 | - } | |
71 | - | |
72 | - public static void hookRightClick(Component component, Predicate<MouseEvent> listener) | |
73 | - { | |
74 | - component.addMouseListener(new MouseListener() { | |
75 | - | |
76 | - @Override | |
77 | - public void mouseReleased(MouseEvent e) | |
78 | - { | |
79 | - | |
80 | - } | |
81 | - | |
82 | - @Override | |
83 | - public void mousePressed(MouseEvent e) | |
84 | - { | |
85 | - | |
86 | - } | |
87 | - | |
88 | - @Override | |
89 | - public void mouseExited(MouseEvent e) | |
90 | - { | |
91 | - | |
92 | - } | |
93 | - | |
94 | - @Override | |
95 | - public void mouseEntered(MouseEvent e) | |
96 | - { | |
97 | - | |
98 | - } | |
99 | - | |
100 | - @Override | |
101 | - public void mouseClicked(MouseEvent e) | |
102 | - { | |
103 | - if (e.getButton() == MouseEvent.BUTTON3) { | |
104 | - if (listener.test(e)) e.consume(); | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - }); | |
109 | - } | |
110 | - | |
111 | - public static void hookPopup(Component component, Predicate<MouseEvent> listener) | |
112 | - { | |
113 | - component.addMouseListener(new MouseListener() { | |
114 | - | |
115 | - @Override | |
116 | - public void mouseReleased(MouseEvent e) | |
117 | - { | |
118 | - if (e.isPopupTrigger()) { | |
119 | - if (listener.test(e)) e.consume(); | |
120 | - } | |
121 | - } | |
122 | - | |
123 | - @Override | |
124 | - public void mousePressed(MouseEvent e) | |
125 | - { | |
126 | - if (e.isPopupTrigger()) { | |
127 | - if (listener.test(e)) e.consume(); | |
128 | - } | |
129 | - } | |
130 | - | |
131 | - @Override | |
132 | - public void mouseExited(MouseEvent e) | |
133 | - { | |
134 | - | |
135 | - } | |
136 | - | |
137 | - @Override | |
138 | - public void mouseEntered(MouseEvent e) | |
139 | - { | |
140 | - | |
141 | - } | |
142 | - | |
143 | - @Override | |
144 | - public void mouseClicked(MouseEvent e) | |
145 | - { | |
146 | - | |
147 | - } | |
148 | - | |
149 | - }); | |
150 | - } | |
151 | - | |
152 | - public static void hookChange(JTextComponent textComponent, Consumer<DocumentEvent> listener) | |
153 | - { | |
154 | - textComponent.getDocument().addDocumentListener(new DocumentListener() { | |
155 | - | |
156 | - @Override | |
157 | - public void insertUpdate(DocumentEvent e) | |
158 | - { | |
159 | - listener.accept(e); | |
160 | - } | |
161 | - | |
162 | - @Override | |
163 | - public void removeUpdate(DocumentEvent e) | |
164 | - { | |
165 | - listener.accept(e); | |
166 | - } | |
167 | - | |
168 | - @Override | |
169 | - public void changedUpdate(DocumentEvent e) | |
170 | - { | |
171 | - listener.accept(e); | |
172 | - } | |
173 | - | |
174 | - }); | |
175 | - } | |
176 | - | |
177 | - public static void hookDoubleClick(Component component, Consumer<MouseEvent> listener) | |
178 | - { | |
179 | - component.addMouseListener(new MouseListener() { | |
180 | - | |
181 | - @Override | |
182 | - public void mouseClicked(MouseEvent e) | |
183 | - { | |
184 | - if (e.getClickCount() == 2) { | |
185 | - listener.accept(e); | |
186 | - } | |
187 | - } | |
188 | - | |
189 | - @Override | |
190 | - public void mousePressed(MouseEvent e) | |
191 | - { | |
192 | - | |
193 | - } | |
194 | - | |
195 | - @Override | |
196 | - public void mouseReleased(MouseEvent e) | |
197 | - { | |
198 | - | |
199 | - } | |
200 | - | |
201 | - @Override | |
202 | - public void mouseEntered(MouseEvent e) | |
203 | - { | |
204 | - | |
205 | - } | |
206 | - | |
207 | - @Override | |
208 | - public void mouseExited(MouseEvent e) | |
209 | - { | |
210 | - | |
211 | - } | |
212 | - | |
213 | - }); | |
214 | - } | |
215 | - | |
216 | -} |
@@ -1,79 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import java.awt.Frame; | |
4 | -import java.awt.Window; | |
5 | -import java.util.Hashtable; | |
6 | - | |
7 | -import javax.swing.ButtonGroup; | |
8 | -import javax.swing.ButtonModel; | |
9 | -import javax.swing.JMenu; | |
10 | -import javax.swing.JRadioButtonMenuItem; | |
11 | -import javax.swing.SwingUtilities; | |
12 | -import javax.swing.UIManager; | |
13 | -import javax.swing.UIManager.LookAndFeelInfo; | |
14 | -import javax.swing.UnsupportedLookAndFeelException; | |
15 | - | |
16 | -import mirrg.swing.helium.logging.HLog; | |
17 | - | |
18 | -public class MenuLookAndFeel extends JMenu | |
19 | -{ | |
20 | - | |
21 | - private ButtonGroup buttonGroup = new ButtonGroup(); | |
22 | - private Hashtable<String, JRadioButtonMenuItem> hashClassNameToRadio = new Hashtable<>(); | |
23 | - | |
24 | - public MenuLookAndFeel() | |
25 | - { | |
26 | - super("LookAndFeel(L)"); | |
27 | - | |
28 | - setMnemonic('L'); | |
29 | - | |
30 | - for (LookAndFeelInfo lookAndFeelInfo : UIManager | |
31 | - .getInstalledLookAndFeels()) { | |
32 | - JRadioButtonMenuItem radio = createRadio(lookAndFeelInfo.getName(), | |
33 | - lookAndFeelInfo.getClassName()); | |
34 | - add(radio); | |
35 | - hashClassNameToRadio.put(lookAndFeelInfo.getClassName(), radio); | |
36 | - } | |
37 | - | |
38 | - addActionListener(e -> { | |
39 | - buttonGroup.setSelected( | |
40 | - hashClassNameToRadio.get( | |
41 | - UIManager.getLookAndFeel().getClass()).getModel(), | |
42 | - true); | |
43 | - }); | |
44 | - } | |
45 | - | |
46 | - protected JRadioButtonMenuItem createRadio(String name, String className) | |
47 | - { | |
48 | - JRadioButtonMenuItem radioButtonMenuItem = new JRadioButtonMenuItem(); | |
49 | - radioButtonMenuItem.setText(name); | |
50 | - radioButtonMenuItem.setActionCommand(className); | |
51 | - radioButtonMenuItem.setHideActionText(true); | |
52 | - radioButtonMenuItem.addActionListener(e -> { | |
53 | - ButtonModel m = buttonGroup.getSelection(); | |
54 | - try { | |
55 | - setLookAndFeel(m.getActionCommand()); | |
56 | - } catch (Exception e1) { | |
57 | - HLog.processException(e1); | |
58 | - } | |
59 | - }); | |
60 | - buttonGroup.add(radioButtonMenuItem); | |
61 | - return radioButtonMenuItem; | |
62 | - } | |
63 | - | |
64 | - public void setLookAndFeel(String lookAndFeel) | |
65 | - throws ClassNotFoundException, InstantiationException, | |
66 | - IllegalAccessException, UnsupportedLookAndFeelException | |
67 | - { | |
68 | - UIManager.setLookAndFeel(lookAndFeel); | |
69 | - updateLookAndFeel(); | |
70 | - } | |
71 | - | |
72 | - private void updateLookAndFeel() | |
73 | - { | |
74 | - for (Window window : Frame.getWindows()) { | |
75 | - SwingUtilities.updateComponentTreeUI(window); | |
76 | - } | |
77 | - } | |
78 | - | |
79 | -} |
@@ -1,29 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import java.util.function.Function; | |
4 | -import java.util.function.Supplier; | |
5 | - | |
6 | -public class NamedSlot<T> implements Supplier<T> | |
7 | -{ | |
8 | - | |
9 | - private T t; | |
10 | - private Function<T, String> functionName; | |
11 | - | |
12 | - public NamedSlot(T t, Function<T, String> functionName) | |
13 | - { | |
14 | - this.t = t; | |
15 | - this.functionName = functionName; | |
16 | - } | |
17 | - | |
18 | - @Override | |
19 | - public String toString() | |
20 | - { | |
21 | - return functionName.apply(t); | |
22 | - } | |
23 | - | |
24 | - public T get() | |
25 | - { | |
26 | - return t; | |
27 | - } | |
28 | - | |
29 | -} |
@@ -1,14 +0,0 @@ | ||
1 | -package mirrg.swing.helium; | |
2 | - | |
3 | -import javax.swing.BorderFactory; | |
4 | -import javax.swing.JComponent; | |
5 | - | |
6 | -public class TitledGroup extends JComponent | |
7 | -{ | |
8 | - | |
9 | - public TitledGroup(String title) | |
10 | - { | |
11 | - if (title != null) setBorder(BorderFactory.createTitledBorder(title)); | |
12 | - } | |
13 | - | |
14 | -} |
@@ -1,10 +0,0 @@ | ||
1 | -package mirrg.swing.helium.logging; | |
2 | - | |
3 | -public enum EnumTypeLog | |
4 | -{ | |
5 | - INFO, | |
6 | - FINE, | |
7 | - WARNING, | |
8 | - ERROR, | |
9 | - UNEXPECTED, | |
10 | -} |
@@ -1,219 +0,0 @@ | ||
1 | -package mirrg.swing.helium.logging; | |
2 | - | |
3 | -import java.awt.CardLayout; | |
4 | -import java.awt.Color; | |
5 | -import java.awt.Dimension; | |
6 | - | |
7 | -import javax.swing.JCheckBox; | |
8 | -import javax.swing.JMenu; | |
9 | -import javax.swing.JMenuBar; | |
10 | -import javax.swing.JMenuItem; | |
11 | -import javax.swing.JScrollBar; | |
12 | -import javax.swing.JScrollPane; | |
13 | -import javax.swing.JTextPane; | |
14 | -import javax.swing.SwingUtilities; | |
15 | -import javax.swing.text.BadLocationException; | |
16 | -import javax.swing.text.DefaultStyledDocument; | |
17 | -import javax.swing.text.Style; | |
18 | -import javax.swing.text.StyleConstants; | |
19 | -import javax.swing.text.StyleContext; | |
20 | - | |
21 | -import mirrg.struct.hydrogen.Tuple; | |
22 | -import mirrg.swing.helium.FrameMirrg; | |
23 | -import mirrg.swing.helium.MenuLookAndFeel; | |
24 | - | |
25 | -public class FrameLog extends FrameMirrg | |
26 | -{ | |
27 | - | |
28 | - public static void main(String[] args) | |
29 | - { | |
30 | - { | |
31 | - HLog.error("Error!"); | |
32 | - HLog.warning("Warning!"); | |
33 | - new FrameLog(300).setVisible(true); | |
34 | - HLog.fine("Fine!"); | |
35 | - HLog.info("Info!"); | |
36 | - new FrameLog(300).setVisible(true); | |
37 | - HLog.info().println("Print Info!"); | |
38 | - new RuntimeException("Exception!").printStackTrace(HLog.warning()); | |
39 | - | |
40 | - Thread thread = new Thread(() -> { | |
41 | - | |
42 | - while (true) { | |
43 | - HLog.info().println("Info!"); | |
44 | - try { | |
45 | - Thread.sleep(1000); | |
46 | - } catch (Exception e) { | |
47 | - break; | |
48 | - } | |
49 | - } | |
50 | - | |
51 | - }); | |
52 | - thread.setDaemon(true); | |
53 | - thread.start(); | |
54 | - } | |
55 | - | |
56 | - { | |
57 | - LoggerMirrg logger = new LoggerMirrg(); | |
58 | - | |
59 | - for (int i = 0; i < 1000; i++) { | |
60 | - logger.info("abc"); | |
61 | - } | |
62 | - | |
63 | - new FrameLog(logger, 300).setVisible(true); | |
64 | - } | |
65 | - | |
66 | - } | |
67 | - | |
68 | - private JCheckBox checkBoxAutoScroll; | |
69 | - private JScrollPane scrollPaneMessages; | |
70 | - private DefaultStyledDocument document; | |
71 | - | |
72 | - public FrameLog(int loadedMessages) | |
73 | - { | |
74 | - this(HLog.logger, loadedMessages); | |
75 | - } | |
76 | - | |
77 | - public FrameLog(LoggerMirrg loggerMirrg, int loadedMessages) | |
78 | - { | |
79 | - super("ログウィンドウ"); | |
80 | - | |
81 | - int skipMessages = loggerMirrg.getMessageCount() - loadedMessages; | |
82 | - | |
83 | - { | |
84 | - JMenuBar menuBar = new JMenuBar(); | |
85 | - setJMenuBar(menuBar); | |
86 | - | |
87 | - { | |
88 | - JMenu menu = new JMenu("メニュー(M)"); | |
89 | - menuBar.add(menu); | |
90 | - | |
91 | - menu.setMnemonic('M'); | |
92 | - | |
93 | - { | |
94 | - JMenu menu2 = new MenuLookAndFeel(); | |
95 | - menu.add(menu2); | |
96 | - } | |
97 | - | |
98 | - { | |
99 | - JMenuItem menuItem = new JMenuItem("ログウィンドウのクリア(C)"); | |
100 | - menu.add(menuItem); | |
101 | - | |
102 | - menuItem.setMnemonic('C'); | |
103 | - menuItem.addActionListener(e -> { | |
104 | - try { | |
105 | - document.remove(0, document.getLength()); | |
106 | - } catch (BadLocationException e1) { | |
107 | - HLog.processExceptionUnexpected(e1); | |
108 | - } | |
109 | - }); | |
110 | - } | |
111 | - } | |
112 | - | |
113 | - { | |
114 | - checkBoxAutoScroll = new JCheckBox("オートスクロール(A)", true); | |
115 | - menuBar.add(checkBoxAutoScroll); | |
116 | - | |
117 | - checkBoxAutoScroll.setMnemonic('A'); | |
118 | - } | |
119 | - | |
120 | - } | |
121 | - | |
122 | - { | |
123 | - document = new DefaultStyledDocument(); | |
124 | - { | |
125 | - Style styleDefault = StyleContext.getDefaultStyleContext().getStyle( | |
126 | - StyleContext.DEFAULT_STYLE); | |
127 | - | |
128 | - Style info = document.addStyle("INFO", styleDefault); | |
129 | - StyleConstants.setForeground(info, Color.BLACK); | |
130 | - | |
131 | - Style fine = document.addStyle("FINE", styleDefault); | |
132 | - StyleConstants.setForeground(fine, new Color(0x0088ff)); | |
133 | - | |
134 | - Style warning = document.addStyle("WARNING", styleDefault); | |
135 | - StyleConstants.setForeground(warning, new Color(0xff8800)); | |
136 | - | |
137 | - Style error = document.addStyle("ERROR", styleDefault); | |
138 | - StyleConstants.setForeground(error, Color.RED); | |
139 | - | |
140 | - Style unexpected = document.addStyle("UNEXPECTED", styleDefault); | |
141 | - StyleConstants.setForeground(unexpected, new Color(0x8800ff)); | |
142 | - | |
143 | - } | |
144 | - | |
145 | - JTextPane textPane = new JTextPane(document); | |
146 | - | |
147 | - textPane.setEditable(false); | |
148 | - | |
149 | - scrollPaneMessages = new JScrollPane(textPane); | |
150 | - scrollPaneMessages.setPreferredSize(new Dimension(400, 400)); | |
151 | - | |
152 | - add(scrollPaneMessages); | |
153 | - } | |
154 | - | |
155 | - setLayout(new CardLayout()); | |
156 | - | |
157 | - hookInitialized(e -> { | |
158 | - | |
159 | - int start = Math.max(0, skipMessages); | |
160 | - | |
161 | - // 省略されたメッセージ | |
162 | - if (start > 0) { | |
163 | - addMessage(new Tuple<>(EnumTypeLog.INFO, "省略された" + start + "件のメッセージ")); | |
164 | - } | |
165 | - | |
166 | - // 既存のメッセージ | |
167 | - for (int i = start; i < loggerMirrg.getMessageCount(); i++) { | |
168 | - addMessage(loggerMirrg.getMessage(i)); | |
169 | - } | |
170 | - | |
171 | - // 新しいメッセージ | |
172 | - loggerMirrg.registerListener(message -> { | |
173 | - if (disabled || isDisposed()) return true; | |
174 | - SwingUtilities.invokeLater(() -> { | |
175 | - addMessage(message); | |
176 | - }); | |
177 | - return false; | |
178 | - }); | |
179 | - | |
180 | - }); | |
181 | - | |
182 | - prepareFrame(); | |
183 | - } | |
184 | - | |
185 | - private transient boolean disabled = false; | |
186 | - | |
187 | - public void disableAcceptMessage() | |
188 | - { | |
189 | - disabled = true; | |
190 | - addMessage(new Tuple<>(EnumTypeLog.INFO, "Log window has been disabled.")); | |
191 | - } | |
192 | - | |
193 | - private void addMessage(Tuple<EnumTypeLog, String> message) | |
194 | - { | |
195 | - try { | |
196 | - | |
197 | - // 追加処理 | |
198 | - document.insertString(document.getLength(), | |
199 | - message.getY() + "\n", | |
200 | - document.getStyle(message.getX().name())); | |
201 | - | |
202 | - // オートスクロール | |
203 | - if (checkBoxAutoScroll.isSelected()) { | |
204 | - scrollPaneMessages.validate(); | |
205 | - JScrollBar scrollBar = scrollPaneMessages.getVerticalScrollBar(); | |
206 | - try { | |
207 | - scrollBar.setValue(scrollBar.getMaximum() - scrollBar.getVisibleAmount()); | |
208 | - } catch (NullPointerException e) { | |
209 | - // なぜか内部で例外が発生する。 | |
210 | - HLog.processExceptionUnexpected(e); | |
211 | - } | |
212 | - } | |
213 | - | |
214 | - } catch (BadLocationException e) { | |
215 | - HLog.processExceptionUnexpected(e); | |
216 | - } | |
217 | - } | |
218 | - | |
219 | -} |
@@ -1,116 +0,0 @@ | ||
1 | -package mirrg.swing.helium.logging; | |
2 | - | |
3 | -import java.io.PrintStream; | |
4 | -import java.util.function.Predicate; | |
5 | - | |
6 | -import mirrg.struct.hydrogen.Tuple; | |
7 | - | |
8 | -public class HLog | |
9 | -{ | |
10 | - | |
11 | - /** | |
12 | - * このロガーは標準出力にも垂れ流す。 | |
13 | - */ | |
14 | - public static final LoggerMirrg logger = new LoggerMirrg(true); | |
15 | - | |
16 | - public static void processException(Exception exception) | |
17 | - { | |
18 | - logger.processException(exception); | |
19 | - } | |
20 | - | |
21 | - public static void processExceptionWarning(Exception exception) | |
22 | - { | |
23 | - logger.processExceptionWarning(exception); | |
24 | - } | |
25 | - | |
26 | - public static void processExceptionUnexpected(Exception exception) | |
27 | - { | |
28 | - logger.processExceptionUnexpected(exception); | |
29 | - } | |
30 | - | |
31 | - public static void processException(Exception exception, String string, boolean isFatal) | |
32 | - { | |
33 | - logger.processException(exception, string, isFatal); | |
34 | - } | |
35 | - | |
36 | - public static void processException(Exception exception, String string, boolean showFrameLog, EnumTypeLog typeLog) | |
37 | - { | |
38 | - logger.processException(exception, string, showFrameLog, typeLog); | |
39 | - } | |
40 | - | |
41 | - public static void info(String string) | |
42 | - { | |
43 | - logger.info(string); | |
44 | - } | |
45 | - | |
46 | - public static void fine(String string) | |
47 | - { | |
48 | - logger.fine(string); | |
49 | - } | |
50 | - | |
51 | - public static void warning(String string) | |
52 | - { | |
53 | - logger.warning(string); | |
54 | - } | |
55 | - | |
56 | - public static void error(String string) | |
57 | - { | |
58 | - logger.error(string); | |
59 | - } | |
60 | - | |
61 | - public static void unexpected(String string) | |
62 | - { | |
63 | - logger.unexpected(string); | |
64 | - } | |
65 | - | |
66 | - public static void log(EnumTypeLog typeLog, String string) | |
67 | - { | |
68 | - logger.log(typeLog, string); | |
69 | - } | |
70 | - | |
71 | - public static PrintStream info() | |
72 | - { | |
73 | - return logger.info(); | |
74 | - } | |
75 | - | |
76 | - public static PrintStream fine() | |
77 | - { | |
78 | - return logger.fine(); | |
79 | - } | |
80 | - | |
81 | - public static PrintStream warning() | |
82 | - { | |
83 | - return logger.warning(); | |
84 | - } | |
85 | - | |
86 | - public static PrintStream error() | |
87 | - { | |
88 | - return logger.error(); | |
89 | - } | |
90 | - | |
91 | - public static PrintStream unexpected() | |
92 | - { | |
93 | - return logger.unexpected(); | |
94 | - } | |
95 | - | |
96 | - public static PrintStream log(EnumTypeLog typeLog) | |
97 | - { | |
98 | - return logger.log(typeLog); | |
99 | - } | |
100 | - | |
101 | - public static int getMessageCount() | |
102 | - { | |
103 | - return logger.getMessageCount(); | |
104 | - } | |
105 | - | |
106 | - public static Tuple<EnumTypeLog, String> getMessage(int index) | |
107 | - { | |
108 | - return logger.getMessage(index); | |
109 | - } | |
110 | - | |
111 | - public static void registerListener(Predicate<Tuple<EnumTypeLog, String>> listener) | |
112 | - { | |
113 | - logger.registerListener(listener); | |
114 | - } | |
115 | - | |
116 | -} |
@@ -1,303 +0,0 @@ | ||
1 | -package mirrg.swing.helium.logging; | |
2 | - | |
3 | -import java.io.IOException; | |
4 | -import java.io.OutputStream; | |
5 | -import java.io.PrintStream; | |
6 | -import java.io.UnsupportedEncodingException; | |
7 | -import java.nio.charset.Charset; | |
8 | -import java.util.ArrayList; | |
9 | -import java.util.Iterator; | |
10 | -import java.util.function.Consumer; | |
11 | -import java.util.function.Predicate; | |
12 | - | |
13 | -import mirrg.struct.hydrogen.Tuple; | |
14 | - | |
15 | -public class LoggerMirrg | |
16 | -{ | |
17 | - | |
18 | - /** | |
19 | - * 例外をerrorとして処理する。ログウィンドウが表示される。 | |
20 | - * | |
21 | - * @see #processException(Exception, String, boolean, EnumTypeLog) | |
22 | - */ | |
23 | - public void processException(Exception exception) | |
24 | - { | |
25 | - processException(exception, null, true, EnumTypeLog.ERROR); | |
26 | - } | |
27 | - | |
28 | - /** | |
29 | - * 例外を想定外の問題として処理する。ログウィンドウは表示されない。 | |
30 | - * | |
31 | - * @see #processException(Exception, String, boolean, EnumTypeLog) | |
32 | - */ | |
33 | - public void processExceptionWarning(Exception exception) | |
34 | - { | |
35 | - processException(exception, null, false, EnumTypeLog.WARNING); | |
36 | - } | |
37 | - | |
38 | - /** | |
39 | - * 例外を想定外の問題として処理する。ログウィンドウが表示される。 | |
40 | - * | |
41 | - * @see #processException(Exception, String, boolean, EnumTypeLog) | |
42 | - */ | |
43 | - public void processExceptionUnexpected(Exception exception) | |
44 | - { | |
45 | - processException(exception, null, true, EnumTypeLog.UNEXPECTED); | |
46 | - } | |
47 | - | |
48 | - /** | |
49 | - * @param isFatal | |
50 | - * 実行中のタスクが停止するような致命的な問題であるか。 | |
51 | - * trueの場合errorとして、falseの場合warningとして扱う。 | |
52 | - * また、trueの場合はログウィンドウを表示する。 | |
53 | - * @see #processException(Exception, String, boolean, EnumTypeLog) | |
54 | - */ | |
55 | - public void processException(Exception exception, String string, boolean isFatal) | |
56 | - { | |
57 | - processException(exception, string, isFatal, | |
58 | - isFatal ? EnumTypeLog.ERROR : EnumTypeLog.WARNING); | |
59 | - } | |
60 | - | |
61 | - /** | |
62 | - * @param exception | |
63 | - * nullable。 | |
64 | - * @param string | |
65 | - * nullable。 | |
66 | - * この例外が発生しているときのシステムの状態。 | |
67 | - */ | |
68 | - public void processException( | |
69 | - Exception exception, | |
70 | - String string, | |
71 | - boolean showFrameLog, | |
72 | - EnumTypeLog typeLog) | |
73 | - { | |
74 | - FrameLog frameLog = null; | |
75 | - if (showFrameLog) { | |
76 | - frameLog = new FrameLog(0); | |
77 | - frameLog.setVisible(true); | |
78 | - } | |
79 | - if (string != null) log(typeLog, string); | |
80 | - if (exception != null) exception.printStackTrace(log(typeLog)); | |
81 | - if (frameLog != null) frameLog.disableAcceptMessage(); | |
82 | - } | |
83 | - | |
84 | - //////////////////////////////////////////////////////// | |
85 | - | |
86 | - public boolean bridgeStdout; | |
87 | - | |
88 | - public LoggerMirrg(boolean bridgeStdout) | |
89 | - { | |
90 | - this.bridgeStdout = bridgeStdout; | |
91 | - } | |
92 | - | |
93 | - public LoggerMirrg() | |
94 | - { | |
95 | - this(false); | |
96 | - } | |
97 | - | |
98 | - public void setBridgeStdout(boolean bridgeStdout) | |
99 | - { | |
100 | - this.bridgeStdout = bridgeStdout; | |
101 | - } | |
102 | - | |
103 | - public boolean isBridgeStdout() | |
104 | - { | |
105 | - return bridgeStdout; | |
106 | - } | |
107 | - | |
108 | - public void info(String string) | |
109 | - { | |
110 | - log(EnumTypeLog.INFO, string); | |
111 | - } | |
112 | - | |
113 | - public void fine(String string) | |
114 | - { | |
115 | - log(EnumTypeLog.FINE, string); | |
116 | - } | |
117 | - | |
118 | - public void warning(String string) | |
119 | - { | |
120 | - log(EnumTypeLog.WARNING, string); | |
121 | - } | |
122 | - | |
123 | - public void error(String string) | |
124 | - { | |
125 | - log(EnumTypeLog.ERROR, string); | |
126 | - } | |
127 | - | |
128 | - public void unexpected(String string) | |
129 | - { | |
130 | - log(EnumTypeLog.UNEXPECTED, string); | |
131 | - } | |
132 | - | |
133 | - public void log(EnumTypeLog typeLog, String string) | |
134 | - { | |
135 | - if (bridgeStdout) System.out.println("[" + typeLog.name() + "] " + string); | |
136 | - | |
137 | - Tuple<EnumTypeLog, String> message = new Tuple<>(typeLog, string); | |
138 | - | |
139 | - messages.add(message); | |
140 | - | |
141 | - Iterator<Predicate<Tuple<EnumTypeLog, String>>> iterator = listeners.iterator(); | |
142 | - while (iterator.hasNext()) { | |
143 | - Predicate<Tuple<EnumTypeLog, String>> next = iterator.next(); | |
144 | - | |
145 | - if (next.test(message)) { | |
146 | - iterator.remove(); | |
147 | - } | |
148 | - } | |
149 | - } | |
150 | - | |
151 | - /////////////////////////////////////////////// | |
152 | - | |
153 | - private PrintStream outInfo; | |
154 | - | |
155 | - public PrintStream info() | |
156 | - { | |
157 | - if (outInfo == null) { | |
158 | - outInfo = createPrintStream(this::info); | |
159 | - } | |
160 | - return outInfo; | |
161 | - } | |
162 | - | |
163 | - private PrintStream outFine; | |
164 | - | |
165 | - public PrintStream fine() | |
166 | - { | |
167 | - if (outFine == null) { | |
168 | - outFine = createPrintStream(this::fine); | |
169 | - } | |
170 | - return outFine; | |
171 | - } | |
172 | - | |
173 | - private PrintStream outWarning; | |
174 | - | |
175 | - public PrintStream warning() | |
176 | - { | |
177 | - if (outWarning == null) { | |
178 | - outWarning = createPrintStream(this::warning); | |
179 | - } | |
180 | - return outWarning; | |
181 | - } | |
182 | - | |
183 | - private PrintStream outError; | |
184 | - | |
185 | - public PrintStream error() | |
186 | - { | |
187 | - if (outError == null) { | |
188 | - outError = createPrintStream(this::error); | |
189 | - } | |
190 | - return outError; | |
191 | - } | |
192 | - | |
193 | - private PrintStream outUnexpected; | |
194 | - | |
195 | - public PrintStream unexpected() | |
196 | - { | |
197 | - if (outUnexpected == null) { | |
198 | - outUnexpected = createPrintStream(this::unexpected); | |
199 | - } | |
200 | - return outUnexpected; | |
201 | - } | |
202 | - | |
203 | - public PrintStream log(EnumTypeLog typeLog) | |
204 | - { | |
205 | - switch (typeLog) { | |
206 | - case INFO: | |
207 | - return info(); | |
208 | - case FINE: | |
209 | - return fine(); | |
210 | - case WARNING: | |
211 | - return warning(); | |
212 | - case ERROR: | |
213 | - return error(); | |
214 | - case UNEXPECTED: | |
215 | - return unexpected(); | |
216 | - default: | |
217 | - return null; | |
218 | - } | |
219 | - } | |
220 | - | |
221 | - private PrintStream createPrintStream(Consumer<String> consumer) | |
222 | - { | |
223 | - try { | |
224 | - return new PrintStream(new OutputStreamLogger(consumer), true, "UTF-8"); | |
225 | - } catch (UnsupportedEncodingException e) { | |
226 | - throw new RuntimeException(e); | |
227 | - } | |
228 | - } | |
229 | - | |
230 | - /////////////////////////////////////////////// | |
231 | - | |
232 | - private ArrayList<Tuple<EnumTypeLog, String>> messages = new ArrayList<>(); | |
233 | - | |
234 | - public int getMessageCount() | |
235 | - { | |
236 | - return messages.size(); | |
237 | - } | |
238 | - | |
239 | - public Tuple<EnumTypeLog, String> getMessage(int index) | |
240 | - { | |
241 | - return messages.get(index); | |
242 | - } | |
243 | - | |
244 | - private ArrayList<Predicate<Tuple<EnumTypeLog, String>>> listeners = new ArrayList<>(); | |
245 | - | |
246 | - /** | |
247 | - * @param listener | |
248 | - * イベントハンドラを削除する場合にtrueを返す。 | |
249 | - */ | |
250 | - public void registerListener(Predicate<Tuple<EnumTypeLog, String>> listener) | |
251 | - { | |
252 | - listeners.add(listener); | |
253 | - } | |
254 | - | |
255 | - private static class OutputStreamLogger extends OutputStream | |
256 | - { | |
257 | - | |
258 | - private static final Charset charset = Charset.forName("UTF-8"); | |
259 | - | |
260 | - private Consumer<String> consumer; | |
261 | - | |
262 | - public OutputStreamLogger(Consumer<String> consumer) | |
263 | - { | |
264 | - this.consumer = consumer; | |
265 | - } | |
266 | - | |
267 | - private ArrayList<Byte> buffer = new ArrayList<>(); | |
268 | - private boolean afterR = false; | |
269 | - | |
270 | - @Override | |
271 | - public void write(int b) throws IOException | |
272 | - { | |
273 | - if (b == '\r') { | |
274 | - flush2(); | |
275 | - } else { | |
276 | - if (b == '\n') { | |
277 | - if (afterR) { | |
278 | - | |
279 | - } else { | |
280 | - flush2(); | |
281 | - } | |
282 | - } else { | |
283 | - buffer.add(Byte.valueOf((byte) b)); | |
284 | - } | |
285 | - } | |
286 | - | |
287 | - afterR = b == '\r'; | |
288 | - } | |
289 | - | |
290 | - private void flush2() | |
291 | - { | |
292 | - byte[] bytes = new byte[buffer.size()]; | |
293 | - for (int i = 0; i < buffer.size(); i++) { | |
294 | - bytes[i] = buffer.get(i); | |
295 | - } | |
296 | - | |
297 | - consumer.accept(new String(bytes, charset)); | |
298 | - buffer.clear(); | |
299 | - } | |
300 | - | |
301 | - } | |
302 | - | |
303 | -} |
@@ -0,0 +1,314 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import java.awt.Component; | |
4 | +import java.awt.Dimension; | |
5 | +import java.awt.event.KeyEvent; | |
6 | +import java.awt.event.KeyListener; | |
7 | +import java.beans.PropertyChangeListener; | |
8 | +import java.io.IOException; | |
9 | +import java.net.URL; | |
10 | +import java.util.LinkedList; | |
11 | + | |
12 | +import javax.swing.GroupLayout; | |
13 | +import javax.swing.GroupLayout.Alignment; | |
14 | +import javax.swing.JButton; | |
15 | +import javax.swing.JEditorPane; | |
16 | +import javax.swing.JLabel; | |
17 | +import javax.swing.JMenuItem; | |
18 | +import javax.swing.JPopupMenu; | |
19 | +import javax.swing.JScrollPane; | |
20 | +import javax.swing.JTextField; | |
21 | +import javax.swing.event.HyperlinkEvent.EventType; | |
22 | +import javax.swing.text.Document; | |
23 | +import javax.swing.text.html.HTMLDocument; | |
24 | + | |
25 | +import mirrg.struct.hydrogen.Struct1; | |
26 | +import mirrg.struct.hydrogen.Tuple; | |
27 | +import mirrg.swing.helium.logging.EnumTypeLog; | |
28 | +import mirrg.swing.helium.logging.HLog; | |
29 | + | |
30 | +public class FrameHTML extends FrameMirrg | |
31 | +{ | |
32 | + | |
33 | + /** | |
34 | + * 下に行くほど新しい。 | |
35 | + */ | |
36 | + private LinkedList<Tuple<URL, Integer>> historyLeft = new LinkedList<>(); | |
37 | + /** | |
38 | + * 下に行くほど新しい。 | |
39 | + */ | |
40 | + private LinkedList<Tuple<URL, Integer>> historyRight = new LinkedList<>(); | |
41 | + | |
42 | + private JButton button1; | |
43 | + private JButton button2; | |
44 | + private JTextField textField1; | |
45 | + private JEditorPane editorPane1; | |
46 | + private JScrollPane scrollPane1; | |
47 | + | |
48 | + public FrameHTML() | |
49 | + { | |
50 | + setTitle("HTMLビューワ"); | |
51 | + | |
52 | + { | |
53 | + | |
54 | + button1 = new JButton("戻る"); | |
55 | + button1.setToolTipText("右クリック:プルダウンメニューの表示"); | |
56 | + button1.addActionListener(e -> { | |
57 | + if (!historyLeft.isEmpty()) travelLeft(1); | |
58 | + }); | |
59 | + HSwing.hookPopup(button1, e -> { | |
60 | + | |
61 | + if (!historyLeft.isEmpty()) { | |
62 | + JPopupMenu popupMenu = new JPopupMenu(); | |
63 | + | |
64 | + for (int i = historyLeft.size() - 1; i >= 0; i--) { | |
65 | + Tuple<URL, Integer> entry = historyLeft.get(i); | |
66 | + JMenuItem menuItem = new JMenuItem( | |
67 | + entry.getY().toString() + ": " + entry.getX().toString()); | |
68 | + popupMenu.add(menuItem); | |
69 | + | |
70 | + int i2 = i + 1; | |
71 | + menuItem.addActionListener(e2 -> { | |
72 | + travelLeft(i2); | |
73 | + }); | |
74 | + } | |
75 | + | |
76 | + popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); | |
77 | + | |
78 | + return true; | |
79 | + } | |
80 | + | |
81 | + return false; | |
82 | + }); | |
83 | + | |
84 | + button2 = new JButton("進む"); | |
85 | + button2.setToolTipText("右クリック:プルダウンメニューの表示"); | |
86 | + button2.addActionListener(e -> { | |
87 | + if (!historyRight.isEmpty()) travelRight(1); | |
88 | + }); | |
89 | + HSwing.hookPopup(button2, e -> { | |
90 | + | |
91 | + if (!historyRight.isEmpty()) { | |
92 | + JPopupMenu popupMenu = new JPopupMenu(); | |
93 | + | |
94 | + for (int i = 0; i < historyRight.size(); i++) { | |
95 | + Tuple<URL, Integer> entry = historyRight.get(i); | |
96 | + JMenuItem menuItem = new JMenuItem( | |
97 | + entry.getY().toString() + ": " + entry.getX().toString()); | |
98 | + popupMenu.add(menuItem); | |
99 | + | |
100 | + int i2 = i + 1; | |
101 | + menuItem.addActionListener(e2 -> { | |
102 | + travelRight(i2); | |
103 | + }); | |
104 | + } | |
105 | + | |
106 | + popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); | |
107 | + | |
108 | + return true; | |
109 | + } | |
110 | + | |
111 | + return false; | |
112 | + }); | |
113 | + | |
114 | + textField1 = new JTextField(); | |
115 | + textField1.addActionListener(e -> { | |
116 | + navigate(textField1.getText()); | |
117 | + }); | |
118 | + | |
119 | + JButton button3 = new JButton("移動"); | |
120 | + button3.addActionListener(e -> { | |
121 | + navigate(textField1.getText()); | |
122 | + }); | |
123 | + | |
124 | + JButton button4 = new JButton("更新"); | |
125 | + button4.addActionListener(e -> { | |
126 | + refresh(); | |
127 | + }); | |
128 | + | |
129 | + editorPane1 = new JEditorPane(); | |
130 | + editorPane1.setEditable(false); | |
131 | + editorPane1.addHyperlinkListener(e -> { | |
132 | + if (e.getEventType() == EventType.ACTIVATED) { | |
133 | + navigate(e.getURL()); | |
134 | + } | |
135 | + }); | |
136 | + editorPane1.addKeyListener(new KeyListener() { | |
137 | + | |
138 | + @Override | |
139 | + public void keyTyped(KeyEvent e) | |
140 | + { | |
141 | + | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + public void keyReleased(KeyEvent e) | |
146 | + { | |
147 | + | |
148 | + } | |
149 | + | |
150 | + @Override | |
151 | + public void keyPressed(KeyEvent e) | |
152 | + { | |
153 | + if (e.getKeyCode() == KeyEvent.VK_F5) { | |
154 | + refresh(); | |
155 | + return; | |
156 | + } | |
157 | + if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) { | |
158 | + if (!historyLeft.isEmpty()) travelLeft(1); | |
159 | + return; | |
160 | + } | |
161 | + } | |
162 | + | |
163 | + }); | |
164 | + | |
165 | + scrollPane1 = new JScrollPane(editorPane1); | |
166 | + scrollPane1.setPreferredSize(new Dimension(800, 800)); | |
167 | + | |
168 | + { | |
169 | + GroupLayout layout = new GroupLayout(getContentPane()); | |
170 | + setLayout(layout); | |
171 | + | |
172 | + layout.setAutoCreateGaps(true); | |
173 | + layout.setAutoCreateContainerGaps(false); | |
174 | + | |
175 | + GroupBuilder.group( | |
176 | + GroupBuilder.group( | |
177 | + button1, | |
178 | + button2, | |
179 | + new JLabel("アドレス:"), | |
180 | + textField1, | |
181 | + button3, | |
182 | + button4 | |
183 | + ).align(Alignment.CENTER), | |
184 | + scrollPane1 | |
185 | + ).apply(layout); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + historyChanged(); | |
190 | + | |
191 | + HLog.log(EnumTypeLog.FINE, "HTMLビューワを起動しました"); | |
192 | + | |
193 | + prepareFrame(); | |
194 | + } | |
195 | + | |
196 | + private void refresh() | |
197 | + { | |
198 | + Tuple<URL, Integer> now = getNow(); | |
199 | + | |
200 | + ((HTMLDocument) editorPane1.getDocument()).getDocumentProperties().remove( | |
201 | + Document.StreamDescriptionProperty); | |
202 | + | |
203 | + if (now != null) setPage(now); | |
204 | + } | |
205 | + | |
206 | + private Tuple<URL, Integer> getNow() | |
207 | + { | |
208 | + URL page = editorPane1.getPage(); | |
209 | + | |
210 | + return page == null | |
211 | + ? null | |
212 | + : new Tuple<>(page, scrollPane1.getVerticalScrollBar().getValue()); | |
213 | + } | |
214 | + | |
215 | + private void travelLeft(int times) | |
216 | + { | |
217 | + Tuple<URL, Integer> now = getNow(); | |
218 | + | |
219 | + // 履歴操作 | |
220 | + for (int i = 0; i < times; i++) { | |
221 | + historyRight.addFirst(now); | |
222 | + now = historyLeft.removeLast(); | |
223 | + } | |
224 | + | |
225 | + historyChanged(); | |
226 | + | |
227 | + setPage(now); | |
228 | + } | |
229 | + | |
230 | + private void travelRight(int times) | |
231 | + { | |
232 | + Tuple<URL, Integer> now = getNow(); | |
233 | + | |
234 | + // 履歴操作 | |
235 | + for (int i = 0; i < times; i++) { | |
236 | + historyLeft.addLast(now); | |
237 | + now = historyRight.removeFirst(); | |
238 | + } | |
239 | + | |
240 | + historyChanged(); | |
241 | + | |
242 | + setPage(now); | |
243 | + } | |
244 | + | |
245 | + private void setPage(Tuple<URL, Integer> url) | |
246 | + { | |
247 | + try { | |
248 | + editorPane1.setPage(url.getX()); | |
249 | + } catch (IOException e) { | |
250 | + HLog.processExceptionWarning(e); | |
251 | + return; | |
252 | + } | |
253 | + | |
254 | + textField1.setText(url.getX().toString()); | |
255 | + | |
256 | + // 表示位置調整 | |
257 | + Struct1<PropertyChangeListener> listener = new Struct1<>(); | |
258 | + listener.x = e -> { | |
259 | + editorPane1.removePropertyChangeListener("page", listener.x); | |
260 | + | |
261 | + scrollPane1.getVerticalScrollBar().setValue(url.getY()); | |
262 | + | |
263 | + }; | |
264 | + editorPane1.addPropertyChangeListener("page", listener.x); | |
265 | + | |
266 | + // 同じページに遷移した場合にイベントが発生しないので念のために変更しておく | |
267 | + // TODO イベントが残留するが次のイベントで死ぬのでとりあえず良しとする | |
268 | + scrollPane1.getVerticalScrollBar().setValue(url.getY()); | |
269 | + | |
270 | + } | |
271 | + | |
272 | + public void navigate(String url) | |
273 | + { | |
274 | + Tuple<URL, Integer> now = getNow(); | |
275 | + if (now != null) { | |
276 | + historyLeft.addLast(now); | |
277 | + historyChanged(); | |
278 | + } | |
279 | + | |
280 | + try { | |
281 | + editorPane1.setPage(url); | |
282 | + } catch (IOException e) { | |
283 | + HLog.processExceptionWarning(e); | |
284 | + return; | |
285 | + } | |
286 | + | |
287 | + textField1.setText(url); | |
288 | + } | |
289 | + | |
290 | + public void navigate(URL url) | |
291 | + { | |
292 | + Tuple<URL, Integer> now = getNow(); | |
293 | + if (now != null) { | |
294 | + historyLeft.addLast(now); | |
295 | + historyChanged(); | |
296 | + } | |
297 | + | |
298 | + try { | |
299 | + editorPane1.setPage(url); | |
300 | + } catch (IOException e) { | |
301 | + HLog.processExceptionWarning(e); | |
302 | + return; | |
303 | + } | |
304 | + | |
305 | + textField1.setText(url.toString()); | |
306 | + } | |
307 | + | |
308 | + private void historyChanged() | |
309 | + { | |
310 | + button1.setEnabled(!historyLeft.isEmpty()); | |
311 | + button2.setEnabled(!historyRight.isEmpty()); | |
312 | + } | |
313 | + | |
314 | +} |
@@ -0,0 +1,205 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import java.awt.GraphicsConfiguration; | |
4 | +import java.awt.HeadlessException; | |
5 | +import java.awt.event.ComponentEvent; | |
6 | +import java.awt.event.ComponentListener; | |
7 | +import java.awt.event.WindowEvent; | |
8 | +import java.awt.event.WindowListener; | |
9 | +import java.util.ArrayList; | |
10 | +import java.util.function.Consumer; | |
11 | + | |
12 | +import javax.swing.JFrame; | |
13 | +import javax.swing.WindowConstants; | |
14 | + | |
15 | +public class FrameMirrg extends JFrame | |
16 | +{ | |
17 | + | |
18 | + public FrameMirrg() throws HeadlessException | |
19 | + { | |
20 | + super(); | |
21 | + initFrameMirrg(); | |
22 | + } | |
23 | + | |
24 | + public FrameMirrg(GraphicsConfiguration gc) | |
25 | + { | |
26 | + super(gc); | |
27 | + initFrameMirrg(); | |
28 | + } | |
29 | + | |
30 | + public FrameMirrg(String title) throws HeadlessException | |
31 | + { | |
32 | + super(title); | |
33 | + initFrameMirrg(); | |
34 | + } | |
35 | + | |
36 | + public FrameMirrg(String title, GraphicsConfiguration gc) | |
37 | + { | |
38 | + super(title, gc); | |
39 | + initFrameMirrg(); | |
40 | + } | |
41 | + | |
42 | + //////////////////////////////////////////////// | |
43 | + | |
44 | + private ArrayList<Consumer<WindowEvent>> listenersOnInitialized = new ArrayList<>(); | |
45 | + private ArrayList<Consumer<ComponentEvent>> listenersOnShown = new ArrayList<>(); | |
46 | + private ArrayList<Consumer<ComponentEvent>> listenersOnHidden = new ArrayList<>(); | |
47 | + private ArrayList<Consumer<WindowEvent>> listenersOnDisposed = new ArrayList<>(); | |
48 | + | |
49 | + /** | |
50 | + * 初回open時 | |
51 | + */ | |
52 | + public void hookInitialized(Consumer<WindowEvent> listener) | |
53 | + { | |
54 | + listenersOnInitialized.add(listener); | |
55 | + } | |
56 | + | |
57 | + /** | |
58 | + * 初回も含めてウィンドウが開くとき | |
59 | + */ | |
60 | + public void hookShown(Consumer<ComponentEvent> listener) | |
61 | + { | |
62 | + listenersOnShown.add(listener); | |
63 | + } | |
64 | + | |
65 | + /** | |
66 | + * disposeも含めてウィンドウが閉じるとき | |
67 | + */ | |
68 | + public void hookHidden(Consumer<ComponentEvent> listener) | |
69 | + { | |
70 | + listenersOnHidden.add(listener); | |
71 | + } | |
72 | + | |
73 | + /** | |
74 | + * disposeするとき | |
75 | + */ | |
76 | + public void hookDisposed(Consumer<WindowEvent> listener) | |
77 | + { | |
78 | + listenersOnDisposed.add(listener); | |
79 | + } | |
80 | + | |
81 | + //////////////////////////////////////////////// | |
82 | + | |
83 | + private boolean visible = false; | |
84 | + | |
85 | + private void initFrameMirrg() | |
86 | + { | |
87 | + addComponentListener(new ComponentListener() { | |
88 | + | |
89 | + @Override | |
90 | + public void componentShown(ComponentEvent e) | |
91 | + { | |
92 | + visible = true; | |
93 | + | |
94 | + listenersOnShown.forEach(listener -> { | |
95 | + listener.accept(e); | |
96 | + }); | |
97 | + } | |
98 | + | |
99 | + @Override | |
100 | + public void componentResized(ComponentEvent e) | |
101 | + { | |
102 | + | |
103 | + } | |
104 | + | |
105 | + @Override | |
106 | + public void componentMoved(ComponentEvent e) | |
107 | + { | |
108 | + | |
109 | + } | |
110 | + | |
111 | + @Override | |
112 | + public void componentHidden(ComponentEvent e) | |
113 | + { | |
114 | + visible = false; | |
115 | + | |
116 | + listenersOnHidden.forEach(listener -> { | |
117 | + listener.accept(e); | |
118 | + }); | |
119 | + } | |
120 | + | |
121 | + }); | |
122 | + addWindowListener(new WindowListener() { | |
123 | + | |
124 | + @Override | |
125 | + public void windowOpened(WindowEvent e) | |
126 | + { | |
127 | + listenersOnInitialized.forEach(listener -> { | |
128 | + listener.accept(e); | |
129 | + }); | |
130 | + } | |
131 | + | |
132 | + @Override | |
133 | + public void windowIconified(WindowEvent e) | |
134 | + { | |
135 | + | |
136 | + } | |
137 | + | |
138 | + @Override | |
139 | + public void windowDeiconified(WindowEvent e) | |
140 | + { | |
141 | + | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + public void windowDeactivated(WindowEvent e) | |
146 | + { | |
147 | + | |
148 | + } | |
149 | + | |
150 | + @Override | |
151 | + public void windowClosing(WindowEvent e) | |
152 | + { | |
153 | + | |
154 | + } | |
155 | + | |
156 | + @Override | |
157 | + public void windowClosed(WindowEvent e) | |
158 | + { | |
159 | + if (visible) { | |
160 | + listenersOnHidden.forEach(listener -> { | |
161 | + listener.accept(e); | |
162 | + }); | |
163 | + } | |
164 | + listenersOnDisposed.forEach(listener -> { | |
165 | + listener.accept(e); | |
166 | + }); | |
167 | + } | |
168 | + | |
169 | + @Override | |
170 | + public void windowActivated(WindowEvent e) | |
171 | + { | |
172 | + | |
173 | + } | |
174 | + | |
175 | + }); | |
176 | + } | |
177 | + | |
178 | + private volatile boolean isDisposed = false; | |
179 | + | |
180 | + /** | |
181 | + * スレッドセーフ | |
182 | + */ | |
183 | + public boolean isDisposed() | |
184 | + { | |
185 | + return isDisposed; | |
186 | + } | |
187 | + | |
188 | + @Override | |
189 | + public void dispose() | |
190 | + { | |
191 | + isDisposed = true; | |
192 | + super.dispose(); | |
193 | + } | |
194 | + | |
195 | + //////////////////////////////////////////////// | |
196 | + | |
197 | + public void prepareFrame() | |
198 | + { | |
199 | + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); | |
200 | + | |
201 | + pack(); | |
202 | + setLocationByPlatform(true); | |
203 | + } | |
204 | + | |
205 | +} |
@@ -0,0 +1,63 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import java.awt.Component; | |
4 | + | |
5 | +import javax.swing.GroupLayout; | |
6 | +import javax.swing.GroupLayout.Alignment; | |
7 | +import javax.swing.GroupLayout.Group; | |
8 | + | |
9 | +public class GroupBuilder | |
10 | +{ | |
11 | + | |
12 | + public static GroupBuilder group(Object... objects) | |
13 | + { | |
14 | + return new GroupBuilder(objects); | |
15 | + } | |
16 | + | |
17 | + private Object[] objects; | |
18 | + private Alignment alignment = null; | |
19 | + | |
20 | + public GroupBuilder(Object[] objects) | |
21 | + { | |
22 | + this.objects = objects; | |
23 | + } | |
24 | + | |
25 | + public Group build(GroupLayout groupLayout) | |
26 | + { | |
27 | + return build(groupLayout, true); | |
28 | + } | |
29 | + | |
30 | + public Group build(GroupLayout groupLayout, boolean isSequential) | |
31 | + { | |
32 | + Group group = isSequential | |
33 | + ? groupLayout.createSequentialGroup() | |
34 | + : alignment != null | |
35 | + ? groupLayout.createParallelGroup(alignment) | |
36 | + : groupLayout.createParallelGroup(); | |
37 | + | |
38 | + for (Object object : objects) { | |
39 | + if (object instanceof GroupBuilder) { | |
40 | + group.addGroup(((GroupBuilder) object).build(groupLayout, !isSequential)); | |
41 | + } else if (object instanceof Component) { | |
42 | + group.addComponent((Component) object); | |
43 | + } else { | |
44 | + throw new RuntimeException("unknown group build entry: " + object); | |
45 | + } | |
46 | + } | |
47 | + | |
48 | + return group; | |
49 | + } | |
50 | + | |
51 | + public void apply(GroupLayout layout) | |
52 | + { | |
53 | + layout.setHorizontalGroup(build(layout, false)); | |
54 | + layout.setVerticalGroup(build(layout)); | |
55 | + } | |
56 | + | |
57 | + public GroupBuilder align(Alignment alignment) | |
58 | + { | |
59 | + this.alignment = alignment; | |
60 | + return this; | |
61 | + } | |
62 | + | |
63 | +} |
@@ -0,0 +1,216 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import java.awt.Component; | |
4 | +import java.awt.Font; | |
5 | +import java.awt.event.MouseEvent; | |
6 | +import java.awt.event.MouseListener; | |
7 | +import java.lang.reflect.Field; | |
8 | +import java.util.function.Consumer; | |
9 | +import java.util.function.Predicate; | |
10 | +import java.util.regex.Pattern; | |
11 | + | |
12 | +import javax.swing.UIManager; | |
13 | +import javax.swing.UIManager.LookAndFeelInfo; | |
14 | +import javax.swing.UnsupportedLookAndFeelException; | |
15 | +import javax.swing.event.DocumentEvent; | |
16 | +import javax.swing.event.DocumentListener; | |
17 | +import javax.swing.text.JTextComponent; | |
18 | + | |
19 | +public class HSwing | |
20 | +{ | |
21 | + | |
22 | + public static void setWindowsLookAndFeel() | |
23 | + { | |
24 | + try { | |
25 | + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); | |
26 | + } catch (ClassNotFoundException e) { | |
27 | + e.printStackTrace(); | |
28 | + } catch (InstantiationException e) { | |
29 | + e.printStackTrace(); | |
30 | + } catch (IllegalAccessException e) { | |
31 | + e.printStackTrace(); | |
32 | + } catch (UnsupportedLookAndFeelException e) { | |
33 | + e.printStackTrace(); | |
34 | + } | |
35 | + } | |
36 | + | |
37 | + public static boolean tryAddWebLookAndFeel() | |
38 | + { | |
39 | + try { | |
40 | + Class<?> clazz = Class.forName("com.alee.laf.WebLookAndFeel"); | |
41 | + if (clazz != null) { | |
42 | + | |
43 | + Field[] fields = clazz.getFields(); | |
44 | + | |
45 | + Pattern pattern = Pattern.compile("global[\\w\\d_]*Font"); | |
46 | + Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 12); | |
47 | + | |
48 | + for (Field field : fields) { | |
49 | + if (pattern.matcher(field.getName()).matches()) { | |
50 | + if (field.getType().isInstance(font)) { | |
51 | + try { | |
52 | + field.set(null, font); | |
53 | + } catch (IllegalArgumentException e) { | |
54 | + e.printStackTrace(); | |
55 | + } catch (IllegalAccessException e) { | |
56 | + e.printStackTrace(); | |
57 | + } | |
58 | + } | |
59 | + } | |
60 | + } | |
61 | + | |
62 | + UIManager.installLookAndFeel(new LookAndFeelInfo(clazz.getSimpleName(), clazz.getName())); | |
63 | + | |
64 | + } | |
65 | + | |
66 | + return true; | |
67 | + } catch (ClassNotFoundException e) { | |
68 | + return false; | |
69 | + } | |
70 | + } | |
71 | + | |
72 | + public static void hookRightClick(Component component, Predicate<MouseEvent> listener) | |
73 | + { | |
74 | + component.addMouseListener(new MouseListener() { | |
75 | + | |
76 | + @Override | |
77 | + public void mouseReleased(MouseEvent e) | |
78 | + { | |
79 | + | |
80 | + } | |
81 | + | |
82 | + @Override | |
83 | + public void mousePressed(MouseEvent e) | |
84 | + { | |
85 | + | |
86 | + } | |
87 | + | |
88 | + @Override | |
89 | + public void mouseExited(MouseEvent e) | |
90 | + { | |
91 | + | |
92 | + } | |
93 | + | |
94 | + @Override | |
95 | + public void mouseEntered(MouseEvent e) | |
96 | + { | |
97 | + | |
98 | + } | |
99 | + | |
100 | + @Override | |
101 | + public void mouseClicked(MouseEvent e) | |
102 | + { | |
103 | + if (e.getButton() == MouseEvent.BUTTON3) { | |
104 | + if (listener.test(e)) e.consume(); | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + }); | |
109 | + } | |
110 | + | |
111 | + public static void hookPopup(Component component, Predicate<MouseEvent> listener) | |
112 | + { | |
113 | + component.addMouseListener(new MouseListener() { | |
114 | + | |
115 | + @Override | |
116 | + public void mouseReleased(MouseEvent e) | |
117 | + { | |
118 | + if (e.isPopupTrigger()) { | |
119 | + if (listener.test(e)) e.consume(); | |
120 | + } | |
121 | + } | |
122 | + | |
123 | + @Override | |
124 | + public void mousePressed(MouseEvent e) | |
125 | + { | |
126 | + if (e.isPopupTrigger()) { | |
127 | + if (listener.test(e)) e.consume(); | |
128 | + } | |
129 | + } | |
130 | + | |
131 | + @Override | |
132 | + public void mouseExited(MouseEvent e) | |
133 | + { | |
134 | + | |
135 | + } | |
136 | + | |
137 | + @Override | |
138 | + public void mouseEntered(MouseEvent e) | |
139 | + { | |
140 | + | |
141 | + } | |
142 | + | |
143 | + @Override | |
144 | + public void mouseClicked(MouseEvent e) | |
145 | + { | |
146 | + | |
147 | + } | |
148 | + | |
149 | + }); | |
150 | + } | |
151 | + | |
152 | + public static void hookChange(JTextComponent textComponent, Consumer<DocumentEvent> listener) | |
153 | + { | |
154 | + textComponent.getDocument().addDocumentListener(new DocumentListener() { | |
155 | + | |
156 | + @Override | |
157 | + public void insertUpdate(DocumentEvent e) | |
158 | + { | |
159 | + listener.accept(e); | |
160 | + } | |
161 | + | |
162 | + @Override | |
163 | + public void removeUpdate(DocumentEvent e) | |
164 | + { | |
165 | + listener.accept(e); | |
166 | + } | |
167 | + | |
168 | + @Override | |
169 | + public void changedUpdate(DocumentEvent e) | |
170 | + { | |
171 | + listener.accept(e); | |
172 | + } | |
173 | + | |
174 | + }); | |
175 | + } | |
176 | + | |
177 | + public static void hookDoubleClick(Component component, Consumer<MouseEvent> listener) | |
178 | + { | |
179 | + component.addMouseListener(new MouseListener() { | |
180 | + | |
181 | + @Override | |
182 | + public void mouseClicked(MouseEvent e) | |
183 | + { | |
184 | + if (e.getClickCount() == 2) { | |
185 | + listener.accept(e); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + @Override | |
190 | + public void mousePressed(MouseEvent e) | |
191 | + { | |
192 | + | |
193 | + } | |
194 | + | |
195 | + @Override | |
196 | + public void mouseReleased(MouseEvent e) | |
197 | + { | |
198 | + | |
199 | + } | |
200 | + | |
201 | + @Override | |
202 | + public void mouseEntered(MouseEvent e) | |
203 | + { | |
204 | + | |
205 | + } | |
206 | + | |
207 | + @Override | |
208 | + public void mouseExited(MouseEvent e) | |
209 | + { | |
210 | + | |
211 | + } | |
212 | + | |
213 | + }); | |
214 | + } | |
215 | + | |
216 | +} |
@@ -0,0 +1,79 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import java.awt.Frame; | |
4 | +import java.awt.Window; | |
5 | +import java.util.Hashtable; | |
6 | + | |
7 | +import javax.swing.ButtonGroup; | |
8 | +import javax.swing.ButtonModel; | |
9 | +import javax.swing.JMenu; | |
10 | +import javax.swing.JRadioButtonMenuItem; | |
11 | +import javax.swing.SwingUtilities; | |
12 | +import javax.swing.UIManager; | |
13 | +import javax.swing.UIManager.LookAndFeelInfo; | |
14 | +import javax.swing.UnsupportedLookAndFeelException; | |
15 | + | |
16 | +import mirrg.swing.helium.logging.HLog; | |
17 | + | |
18 | +public class MenuLookAndFeel extends JMenu | |
19 | +{ | |
20 | + | |
21 | + private ButtonGroup buttonGroup = new ButtonGroup(); | |
22 | + private Hashtable<String, JRadioButtonMenuItem> hashClassNameToRadio = new Hashtable<>(); | |
23 | + | |
24 | + public MenuLookAndFeel() | |
25 | + { | |
26 | + super("LookAndFeel(L)"); | |
27 | + | |
28 | + setMnemonic('L'); | |
29 | + | |
30 | + for (LookAndFeelInfo lookAndFeelInfo : UIManager | |
31 | + .getInstalledLookAndFeels()) { | |
32 | + JRadioButtonMenuItem radio = createRadio(lookAndFeelInfo.getName(), | |
33 | + lookAndFeelInfo.getClassName()); | |
34 | + add(radio); | |
35 | + hashClassNameToRadio.put(lookAndFeelInfo.getClassName(), radio); | |
36 | + } | |
37 | + | |
38 | + addActionListener(e -> { | |
39 | + buttonGroup.setSelected( | |
40 | + hashClassNameToRadio.get( | |
41 | + UIManager.getLookAndFeel().getClass()).getModel(), | |
42 | + true); | |
43 | + }); | |
44 | + } | |
45 | + | |
46 | + protected JRadioButtonMenuItem createRadio(String name, String className) | |
47 | + { | |
48 | + JRadioButtonMenuItem radioButtonMenuItem = new JRadioButtonMenuItem(); | |
49 | + radioButtonMenuItem.setText(name); | |
50 | + radioButtonMenuItem.setActionCommand(className); | |
51 | + radioButtonMenuItem.setHideActionText(true); | |
52 | + radioButtonMenuItem.addActionListener(e -> { | |
53 | + ButtonModel m = buttonGroup.getSelection(); | |
54 | + try { | |
55 | + setLookAndFeel(m.getActionCommand()); | |
56 | + } catch (Exception e1) { | |
57 | + HLog.processException(e1); | |
58 | + } | |
59 | + }); | |
60 | + buttonGroup.add(radioButtonMenuItem); | |
61 | + return radioButtonMenuItem; | |
62 | + } | |
63 | + | |
64 | + public void setLookAndFeel(String lookAndFeel) | |
65 | + throws ClassNotFoundException, InstantiationException, | |
66 | + IllegalAccessException, UnsupportedLookAndFeelException | |
67 | + { | |
68 | + UIManager.setLookAndFeel(lookAndFeel); | |
69 | + updateLookAndFeel(); | |
70 | + } | |
71 | + | |
72 | + private void updateLookAndFeel() | |
73 | + { | |
74 | + for (Window window : Frame.getWindows()) { | |
75 | + SwingUtilities.updateComponentTreeUI(window); | |
76 | + } | |
77 | + } | |
78 | + | |
79 | +} |
@@ -0,0 +1,29 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import java.util.function.Function; | |
4 | +import java.util.function.Supplier; | |
5 | + | |
6 | +public class NamedSlot<T> implements Supplier<T> | |
7 | +{ | |
8 | + | |
9 | + private T t; | |
10 | + private Function<T, String> functionName; | |
11 | + | |
12 | + public NamedSlot(T t, Function<T, String> functionName) | |
13 | + { | |
14 | + this.t = t; | |
15 | + this.functionName = functionName; | |
16 | + } | |
17 | + | |
18 | + @Override | |
19 | + public String toString() | |
20 | + { | |
21 | + return functionName.apply(t); | |
22 | + } | |
23 | + | |
24 | + public T get() | |
25 | + { | |
26 | + return t; | |
27 | + } | |
28 | + | |
29 | +} |
@@ -0,0 +1,14 @@ | ||
1 | +package mirrg.swing.helium; | |
2 | + | |
3 | +import javax.swing.BorderFactory; | |
4 | +import javax.swing.JComponent; | |
5 | + | |
6 | +public class TitledGroup extends JComponent | |
7 | +{ | |
8 | + | |
9 | + public TitledGroup(String title) | |
10 | + { | |
11 | + if (title != null) setBorder(BorderFactory.createTitledBorder(title)); | |
12 | + } | |
13 | + | |
14 | +} |
@@ -0,0 +1,10 @@ | ||
1 | +package mirrg.swing.helium.logging; | |
2 | + | |
3 | +public enum EnumTypeLog | |
4 | +{ | |
5 | + INFO, | |
6 | + FINE, | |
7 | + WARNING, | |
8 | + ERROR, | |
9 | + UNEXPECTED, | |
10 | +} |
@@ -0,0 +1,219 @@ | ||
1 | +package mirrg.swing.helium.logging; | |
2 | + | |
3 | +import java.awt.CardLayout; | |
4 | +import java.awt.Color; | |
5 | +import java.awt.Dimension; | |
6 | + | |
7 | +import javax.swing.JCheckBox; | |
8 | +import javax.swing.JMenu; | |
9 | +import javax.swing.JMenuBar; | |
10 | +import javax.swing.JMenuItem; | |
11 | +import javax.swing.JScrollBar; | |
12 | +import javax.swing.JScrollPane; | |
13 | +import javax.swing.JTextPane; | |
14 | +import javax.swing.SwingUtilities; | |
15 | +import javax.swing.text.BadLocationException; | |
16 | +import javax.swing.text.DefaultStyledDocument; | |
17 | +import javax.swing.text.Style; | |
18 | +import javax.swing.text.StyleConstants; | |
19 | +import javax.swing.text.StyleContext; | |
20 | + | |
21 | +import mirrg.struct.hydrogen.Tuple; | |
22 | +import mirrg.swing.helium.FrameMirrg; | |
23 | +import mirrg.swing.helium.MenuLookAndFeel; | |
24 | + | |
25 | +public class FrameLog extends FrameMirrg | |
26 | +{ | |
27 | + | |
28 | + public static void main(String[] args) | |
29 | + { | |
30 | + { | |
31 | + HLog.error("Error!"); | |
32 | + HLog.warning("Warning!"); | |
33 | + new FrameLog(300).setVisible(true); | |
34 | + HLog.fine("Fine!"); | |
35 | + HLog.info("Info!"); | |
36 | + new FrameLog(300).setVisible(true); | |
37 | + HLog.info().println("Print Info!"); | |
38 | + new RuntimeException("Exception!").printStackTrace(HLog.warning()); | |
39 | + | |
40 | + Thread thread = new Thread(() -> { | |
41 | + | |
42 | + while (true) { | |
43 | + HLog.info().println("Info!"); | |
44 | + try { | |
45 | + Thread.sleep(1000); | |
46 | + } catch (Exception e) { | |
47 | + break; | |
48 | + } | |
49 | + } | |
50 | + | |
51 | + }); | |
52 | + thread.setDaemon(true); | |
53 | + thread.start(); | |
54 | + } | |
55 | + | |
56 | + { | |
57 | + LoggerMirrg logger = new LoggerMirrg(); | |
58 | + | |
59 | + for (int i = 0; i < 1000; i++) { | |
60 | + logger.info("abc"); | |
61 | + } | |
62 | + | |
63 | + new FrameLog(logger, 300).setVisible(true); | |
64 | + } | |
65 | + | |
66 | + } | |
67 | + | |
68 | + private JCheckBox checkBoxAutoScroll; | |
69 | + private JScrollPane scrollPaneMessages; | |
70 | + private DefaultStyledDocument document; | |
71 | + | |
72 | + public FrameLog(int loadedMessages) | |
73 | + { | |
74 | + this(HLog.logger, loadedMessages); | |
75 | + } | |
76 | + | |
77 | + public FrameLog(LoggerMirrg loggerMirrg, int loadedMessages) | |
78 | + { | |
79 | + super("ログウィンドウ"); | |
80 | + | |
81 | + int skipMessages = loggerMirrg.getMessageCount() - loadedMessages; | |
82 | + | |
83 | + { | |
84 | + JMenuBar menuBar = new JMenuBar(); | |
85 | + setJMenuBar(menuBar); | |
86 | + | |
87 | + { | |
88 | + JMenu menu = new JMenu("メニュー(M)"); | |
89 | + menuBar.add(menu); | |
90 | + | |
91 | + menu.setMnemonic('M'); | |
92 | + | |
93 | + { | |
94 | + JMenu menu2 = new MenuLookAndFeel(); | |
95 | + menu.add(menu2); | |
96 | + } | |
97 | + | |
98 | + { | |
99 | + JMenuItem menuItem = new JMenuItem("ログウィンドウのクリア(C)"); | |
100 | + menu.add(menuItem); | |
101 | + | |
102 | + menuItem.setMnemonic('C'); | |
103 | + menuItem.addActionListener(e -> { | |
104 | + try { | |
105 | + document.remove(0, document.getLength()); | |
106 | + } catch (BadLocationException e1) { | |
107 | + HLog.processExceptionUnexpected(e1); | |
108 | + } | |
109 | + }); | |
110 | + } | |
111 | + } | |
112 | + | |
113 | + { | |
114 | + checkBoxAutoScroll = new JCheckBox("オートスクロール(A)", true); | |
115 | + menuBar.add(checkBoxAutoScroll); | |
116 | + | |
117 | + checkBoxAutoScroll.setMnemonic('A'); | |
118 | + } | |
119 | + | |
120 | + } | |
121 | + | |
122 | + { | |
123 | + document = new DefaultStyledDocument(); | |
124 | + { | |
125 | + Style styleDefault = StyleContext.getDefaultStyleContext().getStyle( | |
126 | + StyleContext.DEFAULT_STYLE); | |
127 | + | |
128 | + Style info = document.addStyle("INFO", styleDefault); | |
129 | + StyleConstants.setForeground(info, Color.BLACK); | |
130 | + | |
131 | + Style fine = document.addStyle("FINE", styleDefault); | |
132 | + StyleConstants.setForeground(fine, new Color(0x0088ff)); | |
133 | + | |
134 | + Style warning = document.addStyle("WARNING", styleDefault); | |
135 | + StyleConstants.setForeground(warning, new Color(0xff8800)); | |
136 | + | |
137 | + Style error = document.addStyle("ERROR", styleDefault); | |
138 | + StyleConstants.setForeground(error, Color.RED); | |
139 | + | |
140 | + Style unexpected = document.addStyle("UNEXPECTED", styleDefault); | |
141 | + StyleConstants.setForeground(unexpected, new Color(0x8800ff)); | |
142 | + | |
143 | + } | |
144 | + | |
145 | + JTextPane textPane = new JTextPane(document); | |
146 | + | |
147 | + textPane.setEditable(false); | |
148 | + | |
149 | + scrollPaneMessages = new JScrollPane(textPane); | |
150 | + scrollPaneMessages.setPreferredSize(new Dimension(400, 400)); | |
151 | + | |
152 | + add(scrollPaneMessages); | |
153 | + } | |
154 | + | |
155 | + setLayout(new CardLayout()); | |
156 | + | |
157 | + hookInitialized(e -> { | |
158 | + | |
159 | + int start = Math.max(0, skipMessages); | |
160 | + | |
161 | + // 省略されたメッセージ | |
162 | + if (start > 0) { | |
163 | + addMessage(new Tuple<>(EnumTypeLog.INFO, "省略された" + start + "件のメッセージ")); | |
164 | + } | |
165 | + | |
166 | + // 既存のメッセージ | |
167 | + for (int i = start; i < loggerMirrg.getMessageCount(); i++) { | |
168 | + addMessage(loggerMirrg.getMessage(i)); | |
169 | + } | |
170 | + | |
171 | + // 新しいメッセージ | |
172 | + loggerMirrg.registerListener(message -> { | |
173 | + if (disabled || isDisposed()) return true; | |
174 | + SwingUtilities.invokeLater(() -> { | |
175 | + addMessage(message); | |
176 | + }); | |
177 | + return false; | |
178 | + }); | |
179 | + | |
180 | + }); | |
181 | + | |
182 | + prepareFrame(); | |
183 | + } | |
184 | + | |
185 | + private transient boolean disabled = false; | |
186 | + | |
187 | + public void disableAcceptMessage() | |
188 | + { | |
189 | + disabled = true; | |
190 | + addMessage(new Tuple<>(EnumTypeLog.INFO, "Log window has been disabled.")); | |
191 | + } | |
192 | + | |
193 | + private void addMessage(Tuple<EnumTypeLog, String> message) | |
194 | + { | |
195 | + try { | |
196 | + | |
197 | + // 追加処理 | |
198 | + document.insertString(document.getLength(), | |
199 | + message.getY() + "\n", | |
200 | + document.getStyle(message.getX().name())); | |
201 | + | |
202 | + // オートスクロール | |
203 | + if (checkBoxAutoScroll.isSelected()) { | |
204 | + scrollPaneMessages.validate(); | |
205 | + JScrollBar scrollBar = scrollPaneMessages.getVerticalScrollBar(); | |
206 | + try { | |
207 | + scrollBar.setValue(scrollBar.getMaximum() - scrollBar.getVisibleAmount()); | |
208 | + } catch (NullPointerException e) { | |
209 | + // なぜか内部で例外が発生する。 | |
210 | + HLog.processExceptionUnexpected(e); | |
211 | + } | |
212 | + } | |
213 | + | |
214 | + } catch (BadLocationException e) { | |
215 | + HLog.processExceptionUnexpected(e); | |
216 | + } | |
217 | + } | |
218 | + | |
219 | +} |
@@ -0,0 +1,116 @@ | ||
1 | +package mirrg.swing.helium.logging; | |
2 | + | |
3 | +import java.io.PrintStream; | |
4 | +import java.util.function.Predicate; | |
5 | + | |
6 | +import mirrg.struct.hydrogen.Tuple; | |
7 | + | |
8 | +public class HLog | |
9 | +{ | |
10 | + | |
11 | + /** | |
12 | + * このロガーは標準出力にも垂れ流す。 | |
13 | + */ | |
14 | + public static final LoggerMirrg logger = new LoggerMirrg(true); | |
15 | + | |
16 | + public static void processException(Exception exception) | |
17 | + { | |
18 | + logger.processException(exception); | |
19 | + } | |
20 | + | |
21 | + public static void processExceptionWarning(Exception exception) | |
22 | + { | |
23 | + logger.processExceptionWarning(exception); | |
24 | + } | |
25 | + | |
26 | + public static void processExceptionUnexpected(Exception exception) | |
27 | + { | |
28 | + logger.processExceptionUnexpected(exception); | |
29 | + } | |
30 | + | |
31 | + public static void processException(Exception exception, String string, boolean isFatal) | |
32 | + { | |
33 | + logger.processException(exception, string, isFatal); | |
34 | + } | |
35 | + | |
36 | + public static void processException(Exception exception, String string, boolean showFrameLog, EnumTypeLog typeLog) | |
37 | + { | |
38 | + logger.processException(exception, string, showFrameLog, typeLog); | |
39 | + } | |
40 | + | |
41 | + public static void info(String string) | |
42 | + { | |
43 | + logger.info(string); | |
44 | + } | |
45 | + | |
46 | + public static void fine(String string) | |
47 | + { | |
48 | + logger.fine(string); | |
49 | + } | |
50 | + | |
51 | + public static void warning(String string) | |
52 | + { | |
53 | + logger.warning(string); | |
54 | + } | |
55 | + | |
56 | + public static void error(String string) | |
57 | + { | |
58 | + logger.error(string); | |
59 | + } | |
60 | + | |
61 | + public static void unexpected(String string) | |
62 | + { | |
63 | + logger.unexpected(string); | |
64 | + } | |
65 | + | |
66 | + public static void log(EnumTypeLog typeLog, String string) | |
67 | + { | |
68 | + logger.log(typeLog, string); | |
69 | + } | |
70 | + | |
71 | + public static PrintStream info() | |
72 | + { | |
73 | + return logger.info(); | |
74 | + } | |
75 | + | |
76 | + public static PrintStream fine() | |
77 | + { | |
78 | + return logger.fine(); | |
79 | + } | |
80 | + | |
81 | + public static PrintStream warning() | |
82 | + { | |
83 | + return logger.warning(); | |
84 | + } | |
85 | + | |
86 | + public static PrintStream error() | |
87 | + { | |
88 | + return logger.error(); | |
89 | + } | |
90 | + | |
91 | + public static PrintStream unexpected() | |
92 | + { | |
93 | + return logger.unexpected(); | |
94 | + } | |
95 | + | |
96 | + public static PrintStream log(EnumTypeLog typeLog) | |
97 | + { | |
98 | + return logger.log(typeLog); | |
99 | + } | |
100 | + | |
101 | + public static int getMessageCount() | |
102 | + { | |
103 | + return logger.getMessageCount(); | |
104 | + } | |
105 | + | |
106 | + public static Tuple<EnumTypeLog, String> getMessage(int index) | |
107 | + { | |
108 | + return logger.getMessage(index); | |
109 | + } | |
110 | + | |
111 | + public static void registerListener(Predicate<Tuple<EnumTypeLog, String>> listener) | |
112 | + { | |
113 | + logger.registerListener(listener); | |
114 | + } | |
115 | + | |
116 | +} |
@@ -0,0 +1,303 @@ | ||
1 | +package mirrg.swing.helium.logging; | |
2 | + | |
3 | +import java.io.IOException; | |
4 | +import java.io.OutputStream; | |
5 | +import java.io.PrintStream; | |
6 | +import java.io.UnsupportedEncodingException; | |
7 | +import java.nio.charset.Charset; | |
8 | +import java.util.ArrayList; | |
9 | +import java.util.Iterator; | |
10 | +import java.util.function.Consumer; | |
11 | +import java.util.function.Predicate; | |
12 | + | |
13 | +import mirrg.struct.hydrogen.Tuple; | |
14 | + | |
15 | +public class LoggerMirrg | |
16 | +{ | |
17 | + | |
18 | + /** | |
19 | + * 例外をerrorとして処理する。ログウィンドウが表示される。 | |
20 | + * | |
21 | + * @see #processException(Exception, String, boolean, EnumTypeLog) | |
22 | + */ | |
23 | + public void processException(Exception exception) | |
24 | + { | |
25 | + processException(exception, null, true, EnumTypeLog.ERROR); | |
26 | + } | |
27 | + | |
28 | + /** | |
29 | + * 例外を想定外の問題として処理する。ログウィンドウは表示されない。 | |
30 | + * | |
31 | + * @see #processException(Exception, String, boolean, EnumTypeLog) | |
32 | + */ | |
33 | + public void processExceptionWarning(Exception exception) | |
34 | + { | |
35 | + processException(exception, null, false, EnumTypeLog.WARNING); | |
36 | + } | |
37 | + | |
38 | + /** | |
39 | + * 例外を想定外の問題として処理する。ログウィンドウが表示される。 | |
40 | + * | |
41 | + * @see #processException(Exception, String, boolean, EnumTypeLog) | |
42 | + */ | |
43 | + public void processExceptionUnexpected(Exception exception) | |
44 | + { | |
45 | + processException(exception, null, true, EnumTypeLog.UNEXPECTED); | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * @param isFatal | |
50 | + * 実行中のタスクが停止するような致命的な問題であるか。 | |
51 | + * trueの場合errorとして、falseの場合warningとして扱う。 | |
52 | + * また、trueの場合はログウィンドウを表示する。 | |
53 | + * @see #processException(Exception, String, boolean, EnumTypeLog) | |
54 | + */ | |
55 | + public void processException(Exception exception, String string, boolean isFatal) | |
56 | + { | |
57 | + processException(exception, string, isFatal, | |
58 | + isFatal ? EnumTypeLog.ERROR : EnumTypeLog.WARNING); | |
59 | + } | |
60 | + | |
61 | + /** | |
62 | + * @param exception | |
63 | + * nullable。 | |
64 | + * @param string | |
65 | + * nullable。 | |
66 | + * この例外が発生しているときのシステムの状態。 | |
67 | + */ | |
68 | + public void processException( | |
69 | + Exception exception, | |
70 | + String string, | |
71 | + boolean showFrameLog, | |
72 | + EnumTypeLog typeLog) | |
73 | + { | |
74 | + FrameLog frameLog = null; | |
75 | + if (showFrameLog) { | |
76 | + frameLog = new FrameLog(0); | |
77 | + frameLog.setVisible(true); | |
78 | + } | |
79 | + if (string != null) log(typeLog, string); | |
80 | + if (exception != null) exception.printStackTrace(log(typeLog)); | |
81 | + if (frameLog != null) frameLog.disableAcceptMessage(); | |
82 | + } | |
83 | + | |
84 | + //////////////////////////////////////////////////////// | |
85 | + | |
86 | + public boolean bridgeStdout; | |
87 | + | |
88 | + public LoggerMirrg(boolean bridgeStdout) | |
89 | + { | |
90 | + this.bridgeStdout = bridgeStdout; | |
91 | + } | |
92 | + | |
93 | + public LoggerMirrg() | |
94 | + { | |
95 | + this(false); | |
96 | + } | |
97 | + | |
98 | + public void setBridgeStdout(boolean bridgeStdout) | |
99 | + { | |
100 | + this.bridgeStdout = bridgeStdout; | |
101 | + } | |
102 | + | |
103 | + public boolean isBridgeStdout() | |
104 | + { | |
105 | + return bridgeStdout; | |
106 | + } | |
107 | + | |
108 | + public void info(String string) | |
109 | + { | |
110 | + log(EnumTypeLog.INFO, string); | |
111 | + } | |
112 | + | |
113 | + public void fine(String string) | |
114 | + { | |
115 | + log(EnumTypeLog.FINE, string); | |
116 | + } | |
117 | + | |
118 | + public void warning(String string) | |
119 | + { | |
120 | + log(EnumTypeLog.WARNING, string); | |
121 | + } | |
122 | + | |
123 | + public void error(String string) | |
124 | + { | |
125 | + log(EnumTypeLog.ERROR, string); | |
126 | + } | |
127 | + | |
128 | + public void unexpected(String string) | |
129 | + { | |
130 | + log(EnumTypeLog.UNEXPECTED, string); | |
131 | + } | |
132 | + | |
133 | + public void log(EnumTypeLog typeLog, String string) | |
134 | + { | |
135 | + if (bridgeStdout) System.out.println("[" + typeLog.name() + "] " + string); | |
136 | + | |
137 | + Tuple<EnumTypeLog, String> message = new Tuple<>(typeLog, string); | |
138 | + | |
139 | + messages.add(message); | |
140 | + | |
141 | + Iterator<Predicate<Tuple<EnumTypeLog, String>>> iterator = listeners.iterator(); | |
142 | + while (iterator.hasNext()) { | |
143 | + Predicate<Tuple<EnumTypeLog, String>> next = iterator.next(); | |
144 | + | |
145 | + if (next.test(message)) { | |
146 | + iterator.remove(); | |
147 | + } | |
148 | + } | |
149 | + } | |
150 | + | |
151 | + /////////////////////////////////////////////// | |
152 | + | |
153 | + private PrintStream outInfo; | |
154 | + | |
155 | + public PrintStream info() | |
156 | + { | |
157 | + if (outInfo == null) { | |
158 | + outInfo = createPrintStream(this::info); | |
159 | + } | |
160 | + return outInfo; | |
161 | + } | |
162 | + | |
163 | + private PrintStream outFine; | |
164 | + | |
165 | + public PrintStream fine() | |
166 | + { | |
167 | + if (outFine == null) { | |
168 | + outFine = createPrintStream(this::fine); | |
169 | + } | |
170 | + return outFine; | |
171 | + } | |
172 | + | |
173 | + private PrintStream outWarning; | |
174 | + | |
175 | + public PrintStream warning() | |
176 | + { | |
177 | + if (outWarning == null) { | |
178 | + outWarning = createPrintStream(this::warning); | |
179 | + } | |
180 | + return outWarning; | |
181 | + } | |
182 | + | |
183 | + private PrintStream outError; | |
184 | + | |
185 | + public PrintStream error() | |
186 | + { | |
187 | + if (outError == null) { | |
188 | + outError = createPrintStream(this::error); | |
189 | + } | |
190 | + return outError; | |
191 | + } | |
192 | + | |
193 | + private PrintStream outUnexpected; | |
194 | + | |
195 | + public PrintStream unexpected() | |
196 | + { | |
197 | + if (outUnexpected == null) { | |
198 | + outUnexpected = createPrintStream(this::unexpected); | |
199 | + } | |
200 | + return outUnexpected; | |
201 | + } | |
202 | + | |
203 | + public PrintStream log(EnumTypeLog typeLog) | |
204 | + { | |
205 | + switch (typeLog) { | |
206 | + case INFO: | |
207 | + return info(); | |
208 | + case FINE: | |
209 | + return fine(); | |
210 | + case WARNING: | |
211 | + return warning(); | |
212 | + case ERROR: | |
213 | + return error(); | |
214 | + case UNEXPECTED: | |
215 | + return unexpected(); | |
216 | + default: | |
217 | + return null; | |
218 | + } | |
219 | + } | |
220 | + | |
221 | + private PrintStream createPrintStream(Consumer<String> consumer) | |
222 | + { | |
223 | + try { | |
224 | + return new PrintStream(new OutputStreamLogger(consumer), true, "UTF-8"); | |
225 | + } catch (UnsupportedEncodingException e) { | |
226 | + throw new RuntimeException(e); | |
227 | + } | |
228 | + } | |
229 | + | |
230 | + /////////////////////////////////////////////// | |
231 | + | |
232 | + private ArrayList<Tuple<EnumTypeLog, String>> messages = new ArrayList<>(); | |
233 | + | |
234 | + public int getMessageCount() | |
235 | + { | |
236 | + return messages.size(); | |
237 | + } | |
238 | + | |
239 | + public Tuple<EnumTypeLog, String> getMessage(int index) | |
240 | + { | |
241 | + return messages.get(index); | |
242 | + } | |
243 | + | |
244 | + private ArrayList<Predicate<Tuple<EnumTypeLog, String>>> listeners = new ArrayList<>(); | |
245 | + | |
246 | + /** | |
247 | + * @param listener | |
248 | + * イベントハンドラを削除する場合にtrueを返す。 | |
249 | + */ | |
250 | + public void registerListener(Predicate<Tuple<EnumTypeLog, String>> listener) | |
251 | + { | |
252 | + listeners.add(listener); | |
253 | + } | |
254 | + | |
255 | + private static class OutputStreamLogger extends OutputStream | |
256 | + { | |
257 | + | |
258 | + private static final Charset charset = Charset.forName("UTF-8"); | |
259 | + | |
260 | + private Consumer<String> consumer; | |
261 | + | |
262 | + public OutputStreamLogger(Consumer<String> consumer) | |
263 | + { | |
264 | + this.consumer = consumer; | |
265 | + } | |
266 | + | |
267 | + private ArrayList<Byte> buffer = new ArrayList<>(); | |
268 | + private boolean afterR = false; | |
269 | + | |
270 | + @Override | |
271 | + public void write(int b) throws IOException | |
272 | + { | |
273 | + if (b == '\r') { | |
274 | + flush2(); | |
275 | + } else { | |
276 | + if (b == '\n') { | |
277 | + if (afterR) { | |
278 | + | |
279 | + } else { | |
280 | + flush2(); | |
281 | + } | |
282 | + } else { | |
283 | + buffer.add(Byte.valueOf((byte) b)); | |
284 | + } | |
285 | + } | |
286 | + | |
287 | + afterR = b == '\r'; | |
288 | + } | |
289 | + | |
290 | + private void flush2() | |
291 | + { | |
292 | + byte[] bytes = new byte[buffer.size()]; | |
293 | + for (int i = 0; i < buffer.size(); i++) { | |
294 | + bytes[i] = buffer.get(i); | |
295 | + } | |
296 | + | |
297 | + consumer.accept(new String(bytes, charset)); | |
298 | + buffer.clear(); | |
299 | + } | |
300 | + | |
301 | + } | |
302 | + | |
303 | +} |