add log lines limitation

This commit is contained in:
huangyuhui 2017-07-01 21:31:24 +08:00
parent 979a1a9810
commit 29f53d574c
13 changed files with 322 additions and 139 deletions

23
HMCL/log4j.xml Normal file
View File

@ -0,0 +1,23 @@
<Configuration status="WARN">
<Appenders>
<Console name="SysOut" target="SYSTEM_OUT">
<XMLLayout/>
</Console>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<OnStartupTriggeringPolicy/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<filters>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
</filters>
<AppenderRef ref="SysOut"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>

View File

@ -86,10 +86,13 @@ public final class Config implements Cloneable {
private String fontFamily; private String fontFamily;
@SerializedName("fontSize") @SerializedName("fontSize")
private int fontSize; private int fontSize;
@SerializedName("logLines")
private int logLines;
public Config() { public Config() {
clientToken = UUID.randomUUID().toString(); clientToken = UUID.randomUUID().toString();
logintype = downloadtype = 0; logintype = downloadtype = 0;
logLines = 100;
enableAnimation = enableBlur = true; enableAnimation = enableBlur = true;
if (OS.os() == OS.WINDOWS) if (OS.os() == OS.WINDOWS)
enableShadow = true; enableShadow = true;
@ -315,6 +318,18 @@ public final class Config implements Cloneable {
Settings.save(); Settings.save();
} }
public int getLogLines() {
if (logLines == 100 || logLines == 1000 || logLines == 5000)
return logLines;
else
return logLines = 100;
}
public void setLogLines(int logLines) {
this.logLines = logLines;
Settings.save();
}
@Override @Override
public Object clone() { public Object clone() {
try { try {

View File

@ -29,18 +29,12 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="pnlLog" max="32767" attributes="0"/> <Component id="pnlLog" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="btnTieBa" min="-2" max="-2" attributes="0"/> <Component id="btnContact" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCF" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnGitHub" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Component id="btnTerminateGame" min="-2" max="-2" attributes="0"/> <Component id="btnTerminateGame" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -51,6 +45,21 @@
<Component id="btnClose" min="-2" max="-2" attributes="0"/> <Component id="btnClose" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Component id="lblCrash" alignment="0" max="32767" attributes="0"/> <Component id="lblCrash" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cboShowLines" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="btnFatal" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnError" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnWarn" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnInfo" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnDebug" min="-2" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -59,20 +68,27 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cboShowLines" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnDebug" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnInfo" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnWarn" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnError" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFatal" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblCrash" min="-2" max="-2" attributes="0"/> <Component id="lblCrash" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="pnlLog" pref="356" max="32767" attributes="0"/> <Component id="pnlLog" pref="281" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="btnClear" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnClear" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnClose" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnClose" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnMCBBS" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnContact" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnTieBa" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnMCF" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnGitHub" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -117,30 +133,14 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JButton" name="btnMCBBS"> <Component class="javax.swing.JButton" name="btnContact">
<Properties>
<Property name="text" type="java.lang.String" value="MCBBS"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnTieBa">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hmcl/I18N.properties" key="logwindow.tieba" replaceFormat="C.i18n(&quot;{key}&quot;)"/> <ResourceString bundle="org/jackhuang/hmcl/lang/I18N.properties" key="logwindow.contact" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTieBaActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnContactActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnMCF">
<Properties>
<Property name="text" type="java.lang.String" value="Minecraft Forum"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCFActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JButton" name="btnTerminateGame"> <Component class="javax.swing.JButton" name="btnTerminateGame">
@ -153,14 +153,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTerminateGameActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTerminateGameActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JButton" name="btnGitHub">
<Properties>
<Property name="text" type="java.lang.String" value="GitHub"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnGitHubActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="pnlLog"> <Container class="javax.swing.JScrollPane" name="pnlLog">
<AuxValues> <AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
@ -172,5 +164,53 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="&#x663e;&#x793a;&#x884c;&#x6570;"/>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="cboShowLines">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="3">
<StringItem index="0" value="100"/>
<StringItem index="1" value="1000"/>
<StringItem index="2" value="5000"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboShowLinesItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JToggleButton" name="btnDebug">
<Properties>
<Property name="text" type="java.lang.String" value="debugs"/>
</Properties>
</Component>
<Component class="javax.swing.JToggleButton" name="btnInfo">
<Properties>
<Property name="text" type="java.lang.String" value="infos"/>
</Properties>
</Component>
<Component class="javax.swing.JToggleButton" name="btnWarn">
<Properties>
<Property name="text" type="java.lang.String" value="warns"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnError">
<Properties>
<Property name="text" type="java.lang.String" value="errors"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnFatal">
<Properties>
<Property name="text" type="java.lang.String" value="fatals"/>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -18,6 +18,8 @@
package org.jackhuang.hmcl.ui; package org.jackhuang.hmcl.ui;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Deque;
import java.util.LinkedList;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.text.Document; import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet; import javax.swing.text.SimpleAttributeSet;
@ -73,13 +75,17 @@ public class LogWindow extends javax.swing.JFrame {
btnClose = new javax.swing.JButton(); btnClose = new javax.swing.JButton();
btnCopy = new javax.swing.JButton(); btnCopy = new javax.swing.JButton();
lblCrash = new javax.swing.JLabel(); lblCrash = new javax.swing.JLabel();
btnMCBBS = new javax.swing.JButton(); btnContact = new javax.swing.JButton();
btnTieBa = new javax.swing.JButton();
btnMCF = new javax.swing.JButton();
btnTerminateGame = new javax.swing.JButton(); btnTerminateGame = new javax.swing.JButton();
btnGitHub = new javax.swing.JButton();
pnlLog = new javax.swing.JScrollPane(); pnlLog = new javax.swing.JScrollPane();
txtLog = new javax.swing.JTextPane(); txtLog = new javax.swing.JTextPane();
jLabel1 = new javax.swing.JLabel();
cboShowLines = new javax.swing.JComboBox<>();
btnDebug = new javax.swing.JToggleButton();
btnInfo = new javax.swing.JToggleButton();
btnWarn = new javax.swing.JToggleButton();
btnError = new javax.swing.JButton();
btnFatal = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(C.i18n("logwindow.title")); // NOI18N setTitle(C.i18n("logwindow.title")); // NOI18N
@ -112,24 +118,10 @@ public class LogWindow extends javax.swing.JFrame {
lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N
btnMCBBS.setText("MCBBS"); btnContact.setText(C.i18n("logwindow.contact")); // NOI18N
btnMCBBS.addActionListener(new java.awt.event.ActionListener() { btnContact.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMCBBSActionPerformed(evt); btnContactActionPerformed(evt);
}
});
btnTieBa.setText(C.i18n("logwindow.tieba")); // NOI18N
btnTieBa.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnTieBaActionPerformed(evt);
}
});
btnMCF.setText("Minecraft Forum");
btnMCF.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMCFActionPerformed(evt);
} }
}); });
@ -140,31 +132,38 @@ public class LogWindow extends javax.swing.JFrame {
} }
}); });
btnGitHub.setText("GitHub"); pnlLog.setViewportView(txtLog);
btnGitHub.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { jLabel1.setText("显示行数");
btnGitHubActionPerformed(evt); jLabel1.setToolTipText("");
cboShowLines.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "100", "1000", "5000" }));
cboShowLines.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
cboShowLinesItemStateChanged(evt);
} }
}); });
pnlLog.setViewportView(txtLog); btnDebug.setText("debugs");
btnInfo.setText("infos");
btnWarn.setText("warns");
btnError.setText("errors");
btnFatal.setText("fatals");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnlLog) .addComponent(pnlLog, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(btnTieBa) .addComponent(btnContact)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCBBS)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCF)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnGitHub)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnTerminateGame) .addComponent(btnTerminateGame)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -173,26 +172,46 @@ public class LogWindow extends javax.swing.JFrame {
.addComponent(btnClear) .addComponent(btnClear)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnClose)) .addComponent(btnClose))
.addComponent(lblCrash, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(lblCrash, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cboShowLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnFatal)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnError)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnWarn)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnInfo)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnDebug)))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(cboShowLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnDebug)
.addComponent(btnInfo)
.addComponent(btnWarn)
.addComponent(btnError)
.addComponent(btnFatal))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblCrash) .addComponent(lblCrash)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 356, Short.MAX_VALUE) .addComponent(pnlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnClear) .addComponent(btnClear)
.addComponent(btnClose) .addComponent(btnClose)
.addComponent(btnCopy) .addComponent(btnCopy)
.addComponent(btnMCBBS) .addComponent(btnContact)
.addComponent(btnTieBa) .addComponent(btnTerminateGame))
.addComponent(btnMCF)
.addComponent(btnTerminateGame)
.addComponent(btnGitHub))
.addContainerGap()) .addContainerGap())
); );
@ -213,44 +232,43 @@ public class LogWindow extends javax.swing.JFrame {
Utils.setClipborad(this.txtLog.getText()); Utils.setClipborad(this.txtLog.getText());
}//GEN-LAST:event_btnCopyActionPerformed }//GEN-LAST:event_btnCopyActionPerformed
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed private void btnContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnContactActionPerformed
SwingUtils.openLink(C.URL_PUBLISH); SwingUtils.openLink(C.URL_CONTACT);
}//GEN-LAST:event_btnMCBBSActionPerformed }//GEN-LAST:event_btnContactActionPerformed
private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed
SwingUtils.openLink(C.URL_TIEBA);
}//GEN-LAST:event_btnTieBaActionPerformed
private void btnMCFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCFActionPerformed
SwingUtils.openLink(C.URL_MINECRAFTFORUM);
}//GEN-LAST:event_btnMCFActionPerformed
private void btnTerminateGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTerminateGameActionPerformed private void btnTerminateGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTerminateGameActionPerformed
terminateGames(); terminateGames();
}//GEN-LAST:event_btnTerminateGameActionPerformed }//GEN-LAST:event_btnTerminateGameActionPerformed
private void btnGitHubActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGitHubActionPerformed
SwingUtils.openLink(C.URL_GITHUB);
}//GEN-LAST:event_btnGitHubActionPerformed
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
if (listener != null && listener.apply()) if (listener != null && listener.apply())
terminateGames(); terminateGames();
SwingUtils.exitIfNoWindow(this); SwingUtils.exitIfNoWindow(this);
}//GEN-LAST:event_formWindowClosing }//GEN-LAST:event_formWindowClosing
private void cboShowLinesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboShowLinesItemStateChanged
Settings.getInstance().setLogLines(Integer.parseInt(cboShowLines.getSelectedItem().toString()));
}//GEN-LAST:event_cboShowLinesItemStateChanged
void terminateGames() { void terminateGames() {
ProcessMonitor.stopAll(); ProcessMonitor.stopAll();
} }
int removedLength = 0;
Deque<Integer> offsets = new LinkedList<>();
int fatals = 0, errors = 0, warns = 0, infos = 0, debugs = 0;
public void log(final String status, final Level c) { public void log(final String status, final Level c) {
if (isVisible()) if (!isVisible())
return; return;
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
Document d = txtLog.getStyledDocument(); Document d = txtLog.getStyledDocument();
try { // prevent too much memory used. try { // prevent too much memory used.
if (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() > 1l * 1024 * 1024 * 256) if (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() > 1l * 1024 * 1024 * 256) {
d.remove(0, d.getLength()); d.remove(0, d.getLength());
offsets.clear();
removedLength = 0;
}
} catch (Exception ex) { } catch (Exception ex) {
HMCLog.err("Failed to clear the text component", ex); HMCLog.err("Failed to clear the text component", ex);
} }
@ -258,10 +276,30 @@ public class LogWindow extends javax.swing.JFrame {
SimpleAttributeSet sas = new SimpleAttributeSet(); SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setForeground(sas, c.COLOR); StyleConstants.setForeground(sas, c.COLOR);
try { try {
offsets.add(d.getLength() + removedLength);
d.insertString(d.getLength(), newStatus, sas); d.insertString(d.getLength(), newStatus, sas);
} catch (Exception ex) { } catch (Exception ex) {
HMCLog.err("Failed to insert \"" + newStatus + "\" to " + d.getLength(), ex); HMCLog.err("Failed to insert \"" + newStatus + "\" to " + d.getLength(), ex);
} }
switch (c) {
case FATAL: btnFatal.setText(++fatals + " fatals"); break;
case ERROR: btnError.setText(++errors + " errors"); break;
case WARN: btnWarn.setText(++warns + " warns"); break;
case INFO: btnInfo.setText(++infos + " infos"); break;
case DEBUG: btnDebug.setText(++debugs + " debugs"); break;
}
int maxLines = Integer.parseInt(cboShowLines.getSelectedItem().toString());
while (offsets.size() > maxLines) {
int start = offsets.pollFirst();
int end = offsets.peekFirst();
try {
d.remove(start - removedLength, end - start); // start - removedLength must become 0
removedLength = end;
} catch(Exception ignore) {
}
}
}); });
} }
@ -275,27 +313,25 @@ public class LogWindow extends javax.swing.JFrame {
@Override @Override
public void setVisible(boolean b) { public void setVisible(boolean b) {
cboShowLines.setSelectedItem(Settings.getInstance().getLogLines());
txtLog.setFont(Settings.getInstance().getConsoleFont()); txtLog.setFont(Settings.getInstance().getConsoleFont());
lblCrash.setVisible(false); lblCrash.setVisible(false);
btnMCBBS.setVisible(false); btnContact.setVisible(false);
btnTieBa.setVisible(false);
btnMCF.setVisible(false);
super.setVisible(b); super.setVisible(b);
} }
public void showAsCrashWindow(boolean out_date) { public void showAsCrashWindow(boolean out_date) {
cboShowLines.setSelectedItem(Settings.getInstance().getLogLines());
txtLog.setFont(Settings.getInstance().getConsoleFont()); txtLog.setFont(Settings.getInstance().getConsoleFont());
if (out_date) { if (out_date) {
lblCrash.setVisible(false); lblCrash.setVisible(false);
btnMCBBS.setVisible(false); btnContact.setVisible(false);
btnTieBa.setVisible(false);
btnMCF.setVisible(false);
lblCrash.setText(C.i18n("ui.label.crashing_out_dated")); lblCrash.setText(C.i18n("ui.label.crashing_out_dated"));
} else { } else {
lblCrash.setVisible(true); lblCrash.setVisible(true);
btnMCBBS.setVisible(true); btnContact.setVisible(true);
btnTieBa.setVisible(true);
btnMCF.setVisible(true);
lblCrash.setText(C.i18n("ui.label.crashing")); lblCrash.setText(C.i18n("ui.label.crashing"));
} }
@ -305,12 +341,16 @@ public class LogWindow extends javax.swing.JFrame {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnClear; private javax.swing.JButton btnClear;
private javax.swing.JButton btnClose; private javax.swing.JButton btnClose;
private javax.swing.JButton btnContact;
private javax.swing.JButton btnCopy; private javax.swing.JButton btnCopy;
private javax.swing.JButton btnGitHub; private javax.swing.JToggleButton btnDebug;
private javax.swing.JButton btnMCBBS; private javax.swing.JButton btnError;
private javax.swing.JButton btnMCF; private javax.swing.JButton btnFatal;
private javax.swing.JToggleButton btnInfo;
private javax.swing.JButton btnTerminateGame; private javax.swing.JButton btnTerminateGame;
private javax.swing.JButton btnTieBa; private javax.swing.JToggleButton btnWarn;
private javax.swing.JComboBox<String> cboShowLines;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel lblCrash; private javax.swing.JLabel lblCrash;
private javax.swing.JScrollPane pnlLog; private javax.swing.JScrollPane pnlLog;
private javax.swing.JTextPane txtLog; private javax.swing.JTextPane txtLog;

View File

@ -45,10 +45,16 @@ public class LogWindowOutputStream extends OutputStream {
public final void write(byte[] arr, int off, int len) { public final void write(byte[] arr, int off, int len) {
append(new String(arr, off, len)); append(new String(arr, off, len));
} }
final Object obj = new Object();
Level lastLevel = null;
private void append(final String str) { private void append(final String str) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
txt.log(str, Level.guessLevel(str, sas)); Level level = Level.guessLevel(str);
if (level == null) level = lastLevel;
else lastLevel = level;
txt.log(str, Level.mergeLevel(sas, level));
}); });
} }

View File

@ -31,9 +31,7 @@ public final class C {
//http://repo1.maven.org/maven2 //http://repo1.maven.org/maven2
public static final String URL_PUBLISH = "http://www.mcbbs.net/thread-142335-1-1.html"; public static final String URL_PUBLISH = "http://www.mcbbs.net/thread-142335-1-1.html";
public static final String URL_TIEBA = "http://tieba.baidu.com/f?kw=hellominecraftlauncher"; public static final String URL_CONTACT = "http://huangyuhui.duapp.com/hmcl.php";
public static final String URL_GITHUB = "https://github.com/huanghongxun/HMCL/issues";
public static final String URL_MINECRAFTFORUM = "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265720-hello-minecraft-launcher-1-9-3-mc-1-7-4-auto";
public static final String URL_FORGE_LIST = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/json"; public static final String URL_FORGE_LIST = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/json";
public static final String URL_LITELOADER_LIST = "http://dl.liteloader.com/versions/versions.json"; public static final String URL_LITELOADER_LIST = "http://dl.liteloader.com/versions/versions.json";

View File

@ -51,10 +51,8 @@ public enum Level {
public static final Pattern MINECRAFT_LOGGER_CATEGORY = Pattern.compile("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\] \\[(?<category>[^\\]]+)\\]"); public static final Pattern MINECRAFT_LOGGER_CATEGORY = Pattern.compile("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\] \\[(?<category>[^\\]]+)\\]");
public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*"; public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
public static Level guessLevel(String line, Level preLevel) { public static Level guessLevel(String line) {
if (line.startsWith("MC:")) Level level = null;
line = line.substring("MC:".length());
Level level = preLevel;
Matcher m = MINECRAFT_LOGGER.matcher(line); Matcher m = MINECRAFT_LOGGER.matcher(line);
if (m.find()) { if (m.find()) {
// New style logs from log4j // New style logs from log4j
@ -109,13 +107,23 @@ public enum Level {
if (line.contains("overwriting existing")) if (line.contains("overwriting existing"))
return FATAL; return FATAL;
if (line.contains("Exception in thread") /*if (line.contains("Exception in thread")
|| line.matches("\\s+at " + JAVA_SYMBOL) || line.matches("\\s+at " + JAVA_SYMBOL)
|| line.matches("Caused by: " + JAVA_SYMBOL) || line.matches("Caused by: " + JAVA_SYMBOL)
|| line.matches("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)") || line.matches("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)")
|| line.matches("... \\d+ more$")) || line.matches("... \\d+ more$"))
return ERROR; return ERROR;*/
return preLevel.level < level.level ? preLevel : level; return level;
}
public static boolean isError(Level a) {
return a == null ? false : a.lessOrEqual(Level.ERROR);
}
public static Level mergeLevel(Level a, Level b) {
if (a == null) return b;
else if (b == null) return a;
else return a.level < b.level ? a : b;
} }
} }

View File

@ -32,7 +32,7 @@ import org.jackhuang.hmcl.util.ui.SwingUtils;
public class WebFrame extends JDialog { public class WebFrame extends JDialog {
public WebFrame(String... strs) { public WebFrame(String... strs) {
this(("<html>" + StrUtils.parseParams(t -> ("<font color='#" + GraphicsUtils.getColor(Level.guessLevel((String) t, Level.INFO).COLOR) + "'>"), strs, t -> "</font><br />") + "</html>") this(("<html>" + StrUtils.parseParams(t -> ("<font color='#" + GraphicsUtils.getColor(Level.mergeLevel(Level.INFO, Level.guessLevel((String) t)).COLOR) + "'>"), strs, t -> "</font><br />") + "</html>")
.replace(" ", "&nbsp;").replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;")); .replace(" ", "&nbsp;").replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;"));
} }

View File

@ -41,7 +41,9 @@ public class ProcessMonitor {
public static final HashSet<ProcessMonitor> MONITORS = new HashSet<>(); public static final HashSet<ProcessMonitor> MONITORS = new HashSet<>();
private final CountDownLatch latch = new CountDownLatch(2); private final CountDownLatch latch = new CountDownLatch(2);
ProcessThread inputThread, errorThread; ProcessThread inputThread;
ProcessThread errorThread;
WaitForThread waitForThread;
private final IProcess p; private final IProcess p;
public ProcessMonitor(IProcess p) { public ProcessMonitor(IProcess p) {
@ -83,10 +85,15 @@ public class ProcessMonitor {
private void threadStopped(SimpleEvent<IProcess> event) { private void threadStopped(SimpleEvent<IProcess> event) {
latch.countDown(); latch.countDown();
ProcessThread t = (ProcessThread) event.getSource(); ProcessThread t = (ProcessThread) event.getSource();
HMCLog.log("Process exit code: " + p.getExitCode()); int exitCode = Integer.MAX_VALUE;
try {
exitCode = p.getExitCode();
} catch(IllegalThreadStateException e) {
HMCLog.err("Failed to ");
}
if (p.getExitCode() != 0 || StrUtils.containsOne(t.getLines(), if (p.getExitCode() != 0 || StrUtils.containsOne(t.getLines(),
Arrays.asList("Unable to launch"), Arrays.asList("Unable to launch"), // LaunchWrapper will terminate the application returning exit code 0, but this is an error state.
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR))) x -> Level.isError(Level.guessLevel(x))))
synchronized (this) { synchronized (this) {
if (!hasFired) { if (!hasFired) {
hasFired = true; hasFired = true;
@ -98,7 +105,7 @@ public class ProcessMonitor {
"Error occurred during initialization of VM", "Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.", "A fatal exception has occurred. Program will exit.",
"Unable to launch"), "Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR))) x -> Level.isError(Level.guessLevel(x))))
synchronized (this) { synchronized (this) {
if (!hasFired) { if (!hasFired) {
hasFired = true; hasFired = true;
@ -127,7 +134,6 @@ public class ProcessMonitor {
try { try {
latch.await(); latch.await();
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
HMCLog.warn("Thread has been interrupted.", ignore);
} }
} }
} }

View File

@ -86,7 +86,7 @@ public class ProcessThread extends Thread {
protected void println(String line) { protected void println(String line) {
printlnEvent.fire(new PrintlnEvent(monitor, line, readError)); printlnEvent.fire(new PrintlnEvent(monitor, line, readError));
(readError ? System.err : System.out).println("MC: " + line); (readError ? System.err : System.out).println(line);
lines.add(line); lines.add(line);
p.getStdOutLines().add(line); p.getStdOutLines().add(line);
} }

View File

@ -0,0 +1,47 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.util.sys;
import java.util.concurrent.CountDownLatch;
import org.jackhuang.hmcl.api.HMCLog;
/**
*
* @author huang
*/
public class WaitForThread extends Thread {
CountDownLatch latch;
Runnable done;
public WaitForThread(CountDownLatch latch, Runnable done) {
this.latch = latch;
}
@Override
public void run() {
try {
latch.await();
} catch (InterruptedException ex) {
HMCLog.err("Interrupted latch waiting");
}
done.run();
}
}

View File

@ -123,10 +123,9 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver,
public InstructionsPanelImpl(BufferedImage img, Wizard wizard) { public InstructionsPanelImpl(BufferedImage img, Wizard wizard) {
if (img == null) if (img == null)
try { try {
img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream( img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream("/org/jackhuang/hmcl/wizard.jpg"));
"/org/jackhuang/hmcl/wizard.jpg")); } catch (IOException | NullPointerException ioe) {
} catch (IOException ioe) { HMCLog.err("Failed to load wizard.jpg, maybe you have fuckingly modified the launcher file", ioe);
HMCLog.err("Failed to load wizard.jpg, maybe you fucking modified the launcher", ioe);
} }
this.img = img; this.img = img;
this.wizard = wizard; this.wizard = wizard;

View File

@ -433,3 +433,4 @@ wizard.steps=Steps
lang=English lang=English
lang.default=Belong to OS language. lang.default=Belong to OS language.
logwindow.contact=Contact Us