package com.tax.calculator;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
public class TaxCalculator {
private static final TaxBracket[] TAX_BRACKETS = {
new TaxBracket(0, 36000, 0.03, 0),
new TaxBracket(36000, 144000, 0.10, 2520),
new TaxBracket(144000, 300000, 0.20, 16920),
new TaxBracket(300000, 420000, 0.25, 31920),
new TaxBracket(420000, 660000, 0.30, 52920),
new TaxBracket(660000, 960000, 0.35, 85920),
new TaxBracket(960000, Double.MAX_VALUE, 0.45, 181920)
};
private static final Map<String, BigDecimal> SPECIAL_DEDUCTIONS = new HashMap<>();
static {
SPECIAL_DEDUCTIONS.put("养老", new BigDecimal("1000"));
SPECIAL_DEDUCTIONS.put("医疗", new BigDecimal("200"));
SPECIAL_DEDUCTIONS.put("失业", new BigDecimal("50"));
SPECIAL_DEDUCTIONS.put("住房", new BigDecimal("1200"));
SPECIAL_DEDUCTIONS.put("子女教育", new BigDecimal("1000"));
SPECIAL_DEDUCTIONS.put("继续教育", new BigDecimal("400"));
SPECIAL_DEDUCTIONS.put("大病医疗", new BigDecimal("8000"));
SPECIAL_DEDUCTIONS.put("房贷利息", new BigDecimal("1000"));
SPECIAL_DEDUCTIONS.put("住房租金", new BigDecimal("1500"));
SPECIAL_DEDUCTIONS.put("赡养老人", new BigDecimal("2000"));
}
public static TaxResult calculateAnnualTax(
double annualIncome,
double specialDeductions,
double additionalDeductions) {
final double BASIC_DEDUCTION = 60000;
BigDecimal income = BigDecimal.valueOf(annualIncome);
BigDecimal special = BigDecimal.valueOf(specialDeductions);
BigDecimal additional = BigDecimal.valueOf(additionalDeductions);
BigDecimal basic = BigDecimal.valueOf(BASIC_DEDUCTION);
BigDecimal taxableIncome = income
.subtract(special)
.subtract(additional)
.subtract(basic)
.max(BigDecimal.ZERO);
TaxBracket bracket = findTaxBracket(taxableIncome.doubleValue());
BigDecimal taxAmount = taxableIncome
.multiply(BigDecimal.valueOf(bracket.getRate()))
.subtract(BigDecimal.valueOf(bracket.getQuickDeduction()));
taxAmount = taxAmount.max(BigDecimal.ZERO);
BigDecimal afterTaxIncome = income.subtract(taxAmount);
return new TaxResult(
income.doubleValue(),
taxableIncome.doubleValue(),
taxAmount.doubleValue(),
afterTaxIncome.doubleValue(),
bracket
);
}
private static TaxBracket findTaxBracket(double taxableIncome) {
for (TaxBracket bracket : TAX_BRACKETS) {
if (taxableIncome >= bracket.getLowerBound() &&
taxableIncome < bracket.getUpperBound()) {
return bracket;
}
}
return TAX_BRACKETS[TAX_BRACKETS.length - 1];
}
public static Map<String, BigDecimal> getSpecialDeductionStandards() {
return new HashMap<>(SPECIAL_DEDUCTIONS);
}
public static class TaxBracket {
private final double lowerBound;
private final double upperBound;
private final double rate;
private final double quickDeduction;
public TaxBracket(double lowerBound, double upperBound,
double rate, double quickDeduction) {
this.lowerBound = lowerBound;
this.upperBound = upperBound;
this.rate = rate;
this.quickDeduction = quickDeduction;
}
public double getLowerBound() { return lowerBound; }
public double getUpperBound() { return upperBound; }
public double getRate() { return rate; }
public double getQuickDeduction() { return quickDeduction; }
@Override
public String toString() {
return String.format("税率:%.1f%%, 速算扣除数:%.0f", rate * 100, quickDeduction);
}
}
public static class TaxResult {
private final double totalIncome;
private final double taxableIncome;
private final double taxAmount;
private final double afterTaxIncome;
private final TaxBracket taxBracket;
public TaxResult(double totalIncome, double taxableIncome,
double taxAmount, double afterTaxIncome,
TaxBracket taxBracket) {
this.totalIncome = totalIncome;
this.taxableIncome = taxableIncome;
this.taxAmount = taxAmount;
this.afterTaxIncome = afterTaxIncome;
this.taxBracket = taxBracket;
}
public double getTotalIncome() { return totalIncome; }
public double getTaxableIncome() { return taxableIncome; }
public double getTaxAmount() { return taxAmount; }
public double getAfterTaxIncome() { return afterTaxIncome; }
public TaxBracket getTaxBracket() { return taxBracket; }
@Override
public String toString() {
return String.format(
"计算结果:\n" +
"总收入:¥%.2f\n" +
"应纳税所得额:¥%.2f\n" +
"应纳税额:¥%.2f\n" +
"税后收入:¥%.2f\n" +
"适用税率:%s",
totalIncome, taxableIncome, taxAmount, afterTaxIncome, taxBracket
);
}
}
}
package com.tax.calculator;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.util.Map;
public class TaxCalculatorFrame extends JFrame {
private JTextField incomeField;
private JTextField specialDeductionField;
private JTextField additionalDeductionField;
private JTextArea resultArea;
private JComboBox<String> deductionTypeCombo;
private JLabel standardLabel;
public TaxCalculatorFrame() {
initUI();
initData();
}
private void initUI() {
setTitle("个人所得税计算模拟器 v1.0");
setSize(800, 600);
setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
mainPanel.add(createInputPanel(), BorderLayout.NORTH);
mainPanel.add(createResultPanel(), BorderLayout.CENTER);
mainPanel.add(createButtonPanel(), BorderLayout.SOUTH);
add(mainPanel);
}
private JPanel createInputPanel() {
JPanel panel = new JPanel(new GridLayout(5, 2, 10, 10));
panel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.GRAY),
"个税计算参数输入",
TitledBorder.LEFT,
TitledBorder.TOP
));
panel.add(new JLabel("年度总收入 (¥):"));
incomeField = new JTextField("120000");
panel.add(incomeField);
panel.add(new JLabel("三险一金专项扣除 (¥):"));
specialDeductionField = new JTextField("10000");
panel.add(specialDeductionField);
panel.add(new JLabel("专项附加扣除 (¥):"));
additionalDeductionField = new JTextField("3000");
panel.add(additionalDeductionField);
panel.add(new JLabel("扣除项目查询:"));
JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
deductionTypeCombo = new JComboBox<>();
queryPanel.add(deductionTypeCombo);
standardLabel = new JLabel("标准:¥0");
queryPanel.add(standardLabel);
panel.add(queryPanel);
return panel;
}
private JScrollPane createResultPanel() {
resultArea = new JTextArea();
resultArea.setEditable(false);
resultArea.setFont(new Font("宋体", Font.PLAIN, 14));
resultArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JScrollPane scrollPane = new JScrollPane(resultArea);
scrollPane.setBorder(BorderFactory.createTitledBorder("计算结果"));
return scrollPane;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
JButton calculateBtn = new JButton("计算个税");
calculateBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
calculateBtn.setBackground(new Color(70, 130, 180));
calculateBtn.setForeground(Color.WHITE);
calculateBtn.setPreferredSize(new Dimension(120, 40));
calculateBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
calculateTax();
}
});
JButton clearBtn = new JButton("清除结果");
clearBtn.setFont(new Font("微软雅黑", Font.PLAIN, 14));
clearBtn.setPreferredSize(new Dimension(120, 40));
clearBtn.addActionListener(e -> clearResults());
JButton rateTableBtn = new JButton("查看税率表");
rateTableBtn.setFont(new Font("微软雅黑", Font.PLAIN, 14));
rateTableBtn.setPreferredSize(new Dimension(120, 40));
rateTableBtn.addActionListener(e -> showTaxRateTable());
panel.add(calculateBtn);
panel.add(clearBtn);
panel.add(rateTableBtn);
return panel;
}
private void initData() {
Map<String, BigDecimal> standards = TaxCalculator.getSpecialDeductionStandards();
for (String key : standards.keySet()) {
deductionTypeCombo.addItem(key);
}
deductionTypeCombo.addActionListener(e -> {
String selected = (String) deductionTypeCombo.getSelectedItem();
if (selected != null) {
BigDecimal standard = standards.get(selected);
standardLabel.setText(String.format("标准:¥%.2f", standard));
}
});
if (deductionTypeCombo.getItemCount() > 0) {
deductionTypeCombo.setSelectedIndex(0);
}
}
private void calculateTax() {
try {
double income = Double.parseDouble(incomeField.getText());
double special = Double.parseDouble(specialDeductionField.getText());
double additional = Double.parseDouble(additionalDeductionField.getText());
if (income < 0 || special < 0 || additional < 0) {
JOptionPane.showMessageDialog(this,
"输入值不能为负数!",
"输入错误",
JOptionPane.WARNING_MESSAGE);
return;
}
TaxCalculator.TaxResult result = TaxCalculator.calculateAnnualTax(
income, special, additional);
displayResult(result);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this,
"请输入有效的数字!",
"输入错误",
JOptionPane.ERROR_MESSAGE);
}
}
private void displayResult(TaxCalculator.TaxResult result) {
StringBuilder sb = new StringBuilder();
sb.append("=== 个人所得税计算结果 ===\n\n");
sb.append(String.format("年度总收入:¥%,.2f\n", result.getTotalIncome()));
sb.append(String.format("应纳税所得额:¥%,.2f\n", result.getTaxableIncome()));
sb.append(String.format("适用税率档次:%s\n", result.getTaxBracket()));
sb.append(String.format("应纳个人所得税:¥%,.2f\n", result.getTaxAmount()));
sb.append(String.format("年度税后收入:¥%,.2f\n\n", result.getAfterTaxIncome()));
double monthlyTax = result.getTaxAmount() / 12;
double monthlyAfterTax = result.getAfterTaxIncome() / 12;
sb.append("=== 月度数据估算 ===\n");
sb.append(String.format("月度平均纳税:¥%,.2f\n", monthlyTax));
sb.append(String.format("月度税后收入:¥%,.2f\n\n", monthlyAfterTax));
sb.append("=== 税务优化建议 ===\n");
if (result.getTaxableIncome() > 0) {
sb.append("1. 充分利用专项附加扣除项目\n");
sb.append("2. 合理规划年度收入时间分布\n");
sb.append("3. 符合条件的捐赠可税前扣除\n");
} else {
sb.append("当前收入无需缴纳个人所得税\n");
}
resultArea.setText(sb.toString());
resultArea.setCaretPosition(0);
}
private void showTaxRateTable() {
StringBuilder sb = new StringBuilder();
sb.append("=== 个人所得税税率表(综合所得) ===\n\n");
sb.append("级数 | 全年应纳税所得额 | 税率 | 速算扣除数\n");
sb.append("----|-----------------|------|----------\n");
TaxCalculator.TaxBracket[] brackets = new TaxCalculator.TaxBracket[]{
new TaxCalculator.TaxBracket(0, 36000, 0.03, 0),
new TaxCalculator.TaxBracket(36000, 144000, 0.10, 2520),
new TaxCalculator.TaxBracket(144000, 300000, 0.20, 16920),
new TaxCalculator.TaxBracket(300000, 420000, 0.25, 31920),
new TaxCalculator.TaxBracket(420000, 660000, 0.30, 52920),
new TaxCalculator.TaxBracket(660000, 960000, 0.35, 85920),
new TaxCalculator.TaxBracket(960000, Double.MAX_VALUE, 0.45, 181920)
};
for (int i = 0; i < brackets.length; i++) {
TaxCalculator.TaxBracket b = brackets[i];
String range;
if (b.getUpperBound() == Double.MAX_VALUE) {
range = String.format("超过%,.0f 元", b.getLowerBound());
} else {
range = String.format("%,.0f - %,.0f 元",
b.getLowerBound(), b.getUpperBound());
}
sb.append(String.format("%-4d| %-15s | %.1f%% | %, .0f 元\n",
i + 1, range, b.getRate() * 100, b.getQuickDeduction()));
}
sb.append("\n注:应纳税所得额 = 年度收入 - 6 万元 (基本扣除) - 专项扣除 - 专项附加扣除\n");
resultArea.setText(sb.toString());
}
private void clearResults() {
resultArea.setText("");
}
}